From 9638448c811663bbedb2a23a4b535c1198018a43 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Wed, 29 Jun 2011 17:21:43 +0000 Subject: [PATCH] reference manuals merge is complete! --- Package.cmake.in | 3 +- doc/CMakeLists.txt | 25 +- doc/conf.py | 8 +- doc/ocv.py | 30 +- doc/opencv1/bibliography.rst | 22 - doc/opencv1/c/c_index.rst | 16 - doc/opencv1/c/calib3d.rst | 10 - ...mera_calibration_and_3d_reconstruction.rst | 2609 ------ doc/opencv1/c/core.rst | 14 - doc/opencv1/c/core_basic_structures.rst | 1360 --- doc/opencv1/c/core_clustering.rst | 312 - doc/opencv1/c/core_drawing_functions.rst | 898 -- doc/opencv1/c/core_dynamic_structures.rst | 3723 --------- doc/opencv1/c/core_operations_on_arrays.rst | 7262 ----------------- ...tility_and_system_functions_and_macros.rst | 993 --- doc/opencv1/c/core_xml_yaml_persistence.rst | 2064 ----- doc/opencv1/c/features2d.rst | 10 - ...es2d_feature_detection_and_description.rst | 270 - doc/opencv1/c/highgui.rst | 39 - doc/opencv1/c/highgui_qt_new_functions.rst | 674 -- ...i_reading_and_writing_images_and_video.rst | 726 -- doc/opencv1/c/highgui_user_interface.rst | 728 -- doc/opencv1/c/imgproc.rst | 18 - doc/opencv1/c/imgproc_feature_detection.rst | 721 -- ...mgproc_geometric_image_transformations.rst | 737 -- doc/opencv1/c/imgproc_histograms.rst | 941 --- doc/opencv1/c/imgproc_image_filtering.rst | 681 -- ...oc_miscellaneous_image_transformations.rst | 1404 ---- ...oc_motion_analysis_and_object_tracking.rst | 196 - doc/opencv1/c/imgproc_object_detection.rst | 149 - ...uctural_analysis_and_shape_descriptors.rst | 1766 ---- doc/opencv1/c/objdetect.rst | 10 - .../c/objdetect_cascade_classification.rst | 521 -- doc/opencv1/c/video.rst | 10 - ...eo_motion_analysis_and_object_tracking.rst | 1247 --- doc/opencv1/py/calib3d.rst | 10 - ...mera_calibration_and_3d_reconstruction.rst | 2644 ------ doc/opencv1/py/cookbook.rst | 371 - doc/opencv1/py/core.rst | 16 - doc/opencv1/py/core_basic_structures.rst | 520 -- doc/opencv1/py/core_clustering.rst | 60 - doc/opencv1/py/core_drawing_functions.rst | 967 --- doc/opencv1/py/core_dynamic_structures.rst | 295 - doc/opencv1/py/core_operations_on_arrays.rst | 6914 ---------------- ...tility_and_system_functions_and_macros.rst | 99 - doc/opencv1/py/core_xml_yaml_persistence.rst | 95 - doc/opencv1/py/features2d.rst | 10 - ...es2d_feature_detection_and_description.rst | 264 - doc/opencv1/py/highgui.rst | 38 - ...i_reading_and_writing_images_and_video.rst | 679 -- doc/opencv1/py/highgui_user_interface.rst | 576 -- doc/opencv1/py/imgproc.rst | 18 - doc/opencv1/py/imgproc_feature_detection.rst | 628 -- ...mgproc_geometric_image_transformations.rst | 748 -- doc/opencv1/py/imgproc_histograms.rst | 771 -- doc/opencv1/py/imgproc_image_filtering.rst | 732 -- ...oc_miscellaneous_image_transformations.rst | 1473 ---- ...oc_motion_analysis_and_object_tracking.rst | 216 - doc/opencv1/py/imgproc_object_detection.rst | 155 - .../py/imgproc_planar_subdivisions.rst | 561 -- ...uctural_analysis_and_shape_descriptors.rst | 1484 ---- doc/opencv1/py/introduction.rst | 37 - doc/opencv1/py/objdetect.rst | 10 - .../py/objdetect_cascade_classification.rst | 180 - doc/opencv1/py/py_index.rst | 17 - doc/opencv1/py/video.rst | 10 - ...eo_motion_analysis_and_object_tracking.rst | 1116 --- doc/pics/backprojectpatch.png | Bin 3869 -> 0 bytes doc/pics/bayer.png | Bin 19476 -> 0 bytes doc/pics/boundingrect.png | Bin 1059 -> 0 bytes doc/pics/building.jpg | Bin 79718 -> 0 bytes doc/pics/contoursecarea.png | Bin 2020 -> 0 bytes doc/pics/cornersubpix.png | Bin 1347 -> 0 bytes doc/pics/defects.png | Bin 23393 -> 0 bytes doc/pics/disparity.png | Bin 3039 -> 0 bytes doc/pics/ellipse.png | Bin 2425 -> 0 bytes doc/pics/em1.png | Bin 5725 -> 0 bytes doc/pics/em3.png | Bin 6862 -> 0 bytes doc/pics/em4.png | Bin 2175 -> 0 bytes doc/pics/em5.png | Bin 3826 -> 0 bytes doc/pics/em6.png | Bin 2295 -> 0 bytes doc/pics/em7.png | Bin 2325 -> 0 bytes doc/pics/em8.png | Bin 899 -> 0 bytes doc/pics/em9.png | Bin 5650 -> 0 bytes doc/pics/errmsg.png | Bin 13120 -> 0 bytes doc/pics/face.png | Bin 2055 -> 0 bytes doc/pics/houghp.png | Bin 26751 -> 0 bytes doc/pics/integral.png | Bin 85298 -> 0 bytes doc/pics/inv_logpolar.jpg | Bin 42718 -> 0 bytes doc/pics/left.jpg | Bin 10080 -> 0 bytes doc/pics/logpolar.jpg | Bin 13905 -> 0 bytes doc/pics/maxrect.png | Bin 546 -> 0 bytes doc/pics/minareabox.png | Bin 1395 -> 0 bytes doc/pics/mlp_.png | Bin 11382 -> 0 bytes doc/pics/neuron_model.png | Bin 10005 -> 0 bytes doc/pics/pointpolygon.png | Bin 28475 -> 0 bytes doc/pics/qtgui.png | Bin 379842 -> 0 bytes doc/pics/quadedge.png | Bin 4679 -> 0 bytes doc/pics/right.jpg | Bin 9233 -> 0 bytes doc/pics/sigmoid_bipolar.png | Bin 7151 -> 0 bytes doc/pics/stereo_undistort.jpg | Bin 123022 -> 0 bytes doc/pics/subdiv.png | Bin 2812 -> 0 bytes doc/pics/threshold.png | Bin 4474 -> 0 bytes doc/pics/tsukuba_l.png | Bin 85192 -> 0 bytes doc/pics/tsukuba_r.png | Bin 85104 -> 0 bytes index.rst | 3 - ...mera_calibration_and_3d_reconstruction.rst | 54 +- modules/core/doc/clustering.rst | 3 +- modules/core/doc/core.rst | 3 + modules/core/doc/drawing_functions.rst | 55 +- modules/core/doc/dynamic_structures.rst | 1549 ++++ modules/core/doc/old_basic_structures.rst | 1747 ++++ modules/core/doc/old_xml_yaml_persistence.rst | 909 +++ modules/core/doc/operations_on_arrays.rst | 153 +- .../core/doc}/pics/memstorage1.png | Bin .../core/doc}/pics/memstorage2.png | Bin ...tility_and_system_functions_and_macros.rst | 135 +- modules/core/doc/xml_yaml_persistence.rst | 2 - ...common_interfaces_of_feature_detectors.rst | 95 +- .../doc/feature_detection_and_description.rst | 168 +- modules/features2d/src/orb.cpp | 4 +- ...mera_calibration_and_3d_reconstruction.rst | 31 +- modules/gpu/doc/object_detection.rst | 3 +- .../reading_and_writing_images_and_video.rst | 282 +- modules/highgui/doc/user_interface.rst | 52 + modules/imgproc/doc/feature_detection.rst | 15 +- modules/imgproc/doc/filtering.rst | 120 +- .../imgproc/doc/geometric_transformations.rst | 64 +- modules/imgproc/doc/histograms.rst | 299 +- .../doc/miscellaneous_transformations.rst | 19 +- .../imgproc/doc/planar_subdivisions.rst | 413 +- ...uctural_analysis_and_shape_descriptors.rst | 78 +- modules/ml/doc/boosting.rst | 28 +- modules/ml/doc/decision_trees.rst | 12 +- modules/ml/doc/expectation_maximization.rst | 19 +- modules/ml/doc/gradient_boosted_trees.rst | 14 +- modules/ml/doc/k_nearest_neighbors.rst | 4 +- modules/ml/doc/neural_networks.rst | 27 +- modules/ml/doc/normal_bayes_classifier.rst | 8 +- modules/ml/doc/random_trees.rst | 8 +- modules/ml/doc/statistical_models.rst | 4 +- modules/ml/doc/support_vector_machines.rst | 38 +- .../objdetect/doc/cascade_classification.rst | 127 +- .../objdetect/doc}/pics/haarfeatures.png | Bin modules/python/src2/gen2.py | 5 +- modules/refman.rst | 2 +- .../motion_analysis_and_object_tracking.rst | 63 +- 147 files changed, 5790 insertions(+), 52736 deletions(-) delete mode 100644 doc/opencv1/bibliography.rst delete mode 100644 doc/opencv1/c/c_index.rst delete mode 100644 doc/opencv1/c/calib3d.rst delete mode 100644 doc/opencv1/c/calib3d_camera_calibration_and_3d_reconstruction.rst delete mode 100644 doc/opencv1/c/core.rst delete mode 100644 doc/opencv1/c/core_basic_structures.rst delete mode 100644 doc/opencv1/c/core_clustering.rst delete mode 100644 doc/opencv1/c/core_drawing_functions.rst delete mode 100644 doc/opencv1/c/core_dynamic_structures.rst delete mode 100644 doc/opencv1/c/core_operations_on_arrays.rst delete mode 100644 doc/opencv1/c/core_utility_and_system_functions_and_macros.rst delete mode 100644 doc/opencv1/c/core_xml_yaml_persistence.rst delete mode 100644 doc/opencv1/c/features2d.rst delete mode 100644 doc/opencv1/c/features2d_feature_detection_and_description.rst delete mode 100644 doc/opencv1/c/highgui.rst delete mode 100644 doc/opencv1/c/highgui_qt_new_functions.rst delete mode 100644 doc/opencv1/c/highgui_reading_and_writing_images_and_video.rst delete mode 100644 doc/opencv1/c/highgui_user_interface.rst delete mode 100644 doc/opencv1/c/imgproc.rst delete mode 100644 doc/opencv1/c/imgproc_feature_detection.rst delete mode 100644 doc/opencv1/c/imgproc_geometric_image_transformations.rst delete mode 100644 doc/opencv1/c/imgproc_histograms.rst delete mode 100644 doc/opencv1/c/imgproc_image_filtering.rst delete mode 100644 doc/opencv1/c/imgproc_miscellaneous_image_transformations.rst delete mode 100644 doc/opencv1/c/imgproc_motion_analysis_and_object_tracking.rst delete mode 100644 doc/opencv1/c/imgproc_object_detection.rst delete mode 100644 doc/opencv1/c/imgproc_structural_analysis_and_shape_descriptors.rst delete mode 100644 doc/opencv1/c/objdetect.rst delete mode 100644 doc/opencv1/c/objdetect_cascade_classification.rst delete mode 100644 doc/opencv1/c/video.rst delete mode 100644 doc/opencv1/c/video_motion_analysis_and_object_tracking.rst delete mode 100644 doc/opencv1/py/calib3d.rst delete mode 100644 doc/opencv1/py/calib3d_camera_calibration_and_3d_reconstruction.rst delete mode 100644 doc/opencv1/py/cookbook.rst delete mode 100644 doc/opencv1/py/core.rst delete mode 100644 doc/opencv1/py/core_basic_structures.rst delete mode 100644 doc/opencv1/py/core_clustering.rst delete mode 100644 doc/opencv1/py/core_drawing_functions.rst delete mode 100644 doc/opencv1/py/core_dynamic_structures.rst delete mode 100644 doc/opencv1/py/core_operations_on_arrays.rst delete mode 100644 doc/opencv1/py/core_utility_and_system_functions_and_macros.rst delete mode 100644 doc/opencv1/py/core_xml_yaml_persistence.rst delete mode 100644 doc/opencv1/py/features2d.rst delete mode 100644 doc/opencv1/py/features2d_feature_detection_and_description.rst delete mode 100644 doc/opencv1/py/highgui.rst delete mode 100644 doc/opencv1/py/highgui_reading_and_writing_images_and_video.rst delete mode 100644 doc/opencv1/py/highgui_user_interface.rst delete mode 100644 doc/opencv1/py/imgproc.rst delete mode 100644 doc/opencv1/py/imgproc_feature_detection.rst delete mode 100644 doc/opencv1/py/imgproc_geometric_image_transformations.rst delete mode 100644 doc/opencv1/py/imgproc_histograms.rst delete mode 100644 doc/opencv1/py/imgproc_image_filtering.rst delete mode 100644 doc/opencv1/py/imgproc_miscellaneous_image_transformations.rst delete mode 100644 doc/opencv1/py/imgproc_motion_analysis_and_object_tracking.rst delete mode 100644 doc/opencv1/py/imgproc_object_detection.rst delete mode 100644 doc/opencv1/py/imgproc_planar_subdivisions.rst delete mode 100644 doc/opencv1/py/imgproc_structural_analysis_and_shape_descriptors.rst delete mode 100644 doc/opencv1/py/introduction.rst delete mode 100644 doc/opencv1/py/objdetect.rst delete mode 100644 doc/opencv1/py/objdetect_cascade_classification.rst delete mode 100644 doc/opencv1/py/py_index.rst delete mode 100644 doc/opencv1/py/video.rst delete mode 100644 doc/opencv1/py/video_motion_analysis_and_object_tracking.rst delete mode 100644 doc/pics/backprojectpatch.png delete mode 100644 doc/pics/bayer.png delete mode 100644 doc/pics/boundingrect.png delete mode 100644 doc/pics/building.jpg delete mode 100644 doc/pics/contoursecarea.png delete mode 100644 doc/pics/cornersubpix.png delete mode 100644 doc/pics/defects.png delete mode 100644 doc/pics/disparity.png delete mode 100644 doc/pics/ellipse.png delete mode 100644 doc/pics/em1.png delete mode 100644 doc/pics/em3.png delete mode 100644 doc/pics/em4.png delete mode 100644 doc/pics/em5.png delete mode 100644 doc/pics/em6.png delete mode 100644 doc/pics/em7.png delete mode 100644 doc/pics/em8.png delete mode 100644 doc/pics/em9.png delete mode 100644 doc/pics/errmsg.png delete mode 100644 doc/pics/face.png delete mode 100644 doc/pics/houghp.png delete mode 100644 doc/pics/integral.png delete mode 100644 doc/pics/inv_logpolar.jpg delete mode 100644 doc/pics/left.jpg delete mode 100644 doc/pics/logpolar.jpg delete mode 100644 doc/pics/maxrect.png delete mode 100644 doc/pics/minareabox.png delete mode 100644 doc/pics/mlp_.png delete mode 100644 doc/pics/neuron_model.png delete mode 100644 doc/pics/pointpolygon.png delete mode 100644 doc/pics/qtgui.png delete mode 100644 doc/pics/quadedge.png delete mode 100644 doc/pics/right.jpg delete mode 100644 doc/pics/sigmoid_bipolar.png delete mode 100644 doc/pics/stereo_undistort.jpg delete mode 100644 doc/pics/subdiv.png delete mode 100644 doc/pics/threshold.png delete mode 100644 doc/pics/tsukuba_l.png delete mode 100644 doc/pics/tsukuba_r.png create mode 100644 modules/core/doc/dynamic_structures.rst create mode 100644 modules/core/doc/old_basic_structures.rst create mode 100644 modules/core/doc/old_xml_yaml_persistence.rst rename {doc => modules/core/doc}/pics/memstorage1.png (100%) rename {doc => modules/core/doc}/pics/memstorage2.png (100%) rename doc/opencv1/c/imgproc_planar_subdivisions.rst => modules/imgproc/doc/planar_subdivisions.rst (64%) rename {doc => modules/objdetect/doc}/pics/haarfeatures.png (100%) diff --git a/Package.cmake.in b/Package.cmake.in index d50c85e2eb..473c534c96 100644 --- a/Package.cmake.in +++ b/Package.cmake.in @@ -89,8 +89,7 @@ if(WIN32) set(CPACK_NSIS_MENU_LINKS "http://opencv.willowgarage.com" "Start Page" - "doc\\\\opencv2refman_cpp.pdf" "The OpenCV C++ Reference Manual" - "doc\\\\opencv2refman_py.pdf" "The OpenCV Python Reference Manual" + "doc\\\\opencv2refman.pdf" "The OpenCV Reference Manual" "doc\\\\opencv_tutorials.pdf" "The OpenCV Tutorials for Beginners" "CMakeLists.txt" "The Build Script (open with CMake)" "samples\\\\c" "C Samples" diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 7a03fa1934..d5d65bf6f9 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -11,17 +11,14 @@ if(BUILD_DOCS AND PDFLATEX_COMPILER AND HAVE_SPHINX) project(opencv_docs) -file(GLOB_RECURSE OPENCV2_FILES_PICT ../modules/*.png ../modules/*.jpg) -file(GLOB_RECURSE OPENCV2_FILES_RST ../modules/*.rst) -file(GLOB_RECURSE OPENCV2_PY_FILES_RST opencv2/*.rst) -file(GLOB_RECURSE OPENCV1_FILES_PICT pics/*.png pics/*.jpg) -file(GLOB_RECURSE OPENCV1_FILES_RST opencv1/*.rst) +file(GLOB_RECURSE OPENCV_FILES_REF ../modules/*.rst) +file(GLOB_RECURSE OPENCV_FILES_REF_PICT ../modules/*.png ../modules/*.jpg) file(GLOB_RECURSE OPENCV_FILES_UG user_guide/*.rst) file(GLOB_RECURSE OPENCV_FILES_TUT tutorials/*.rst) +file(GLOB_RECURSE OPENCV_FILES_TUT_PICT tutorials/*.png tutorials/*.jpg) -set(OPENCV_DOC_DEPS conf.py ${OPENCV2_FILES_RST} ${OPENCV2_FILES_PICT} ${OPENCV2_PY_FILES_RST} - ${OPENCV1_FILES_RST} ${OPENCV1_FILES_PICT} - ${OPENCV_FILES_UG} ${OPENCV_FILES_TUT}) +set(OPENCV_DOC_DEPS conf.py ${OPENCV_FILES_REF} ${OPENCV_FILES_REF_PICT} + ${OPENCV_FILES_UG} ${OPENCV_FILES_TUT} ${OPENCV_FILES_TUT_PICT}) add_custom_target(docs ${SPHINX_BUILD} @@ -31,14 +28,8 @@ add_custom_target(docs ${CMAKE_CURRENT_SOURCE_DIR}/pics ${CMAKE_CURRENT_BINARY_DIR}/doc/opencv1/pics COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/mymath.sty ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${PDFLATEX_COMPILER} opencv2refman_cpp - COMMAND ${PDFLATEX_COMPILER} opencv2refman_cpp - COMMAND ${PDFLATEX_COMPILER} opencv2refman_py - COMMAND ${PDFLATEX_COMPILER} opencv2refman_py - COMMAND ${PDFLATEX_COMPILER} opencv1refman_c - COMMAND ${PDFLATEX_COMPILER} opencv1refman_c - COMMAND ${PDFLATEX_COMPILER} opencv1refman_py - COMMAND ${PDFLATEX_COMPILER} opencv1refman_py + COMMAND ${PDFLATEX_COMPILER} opencv2refman + COMMAND ${PDFLATEX_COMPILER} opencv2refman COMMAND ${PDFLATEX_COMPILER} opencv_user COMMAND ${PDFLATEX_COMPILER} opencv_user COMMAND ${PDFLATEX_COMPILER} opencv_tutorials @@ -51,8 +42,6 @@ add_custom_target(html_docs ${SPHINX_BUILD} -b html -c ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/.. ./_html - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/pics ${CMAKE_CURRENT_BINARY_DIR}/doc/opencv1/pics COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/mymath.sty ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${OPENCV_DOC_DEPS} diff --git a/doc/conf.py b/doc/conf.py index 223d8cb4e9..94207bdd4c 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -223,13 +223,7 @@ pngmath_latex_preamble = r""" # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('modules/refman', 'opencv2refman_cpp.tex', u'The OpenCV 2.x C++ Reference Manual', - u'', 'manual'), - ('doc/opencv2/py/py_index', 'opencv2refman_py.tex', u'The OpenCV 2.x Python Reference Manual', - u'', 'manual'), - ('doc/opencv1/c/c_index', 'opencv1refman_c.tex', u'The OpenCV 1.x C Reference Manual', - u'', 'manual'), - ('doc/opencv1/py/py_index', 'opencv1refman_py.tex', u'The OpenCV 1.x Python Reference Manual', + ('modules/refman', 'opencv2refman.tex', u'The OpenCV Reference Manual', u'', 'manual'), ('doc/user_guide/user_guide', 'opencv_user.tex', u'The OpenCV User Guide', u'', 'manual'), diff --git a/doc/ocv.py b/doc/ocv.py index 3db02b65ab..566bda7df1 100644 --- a/doc/ocv.py +++ b/doc/ocv.py @@ -1081,6 +1081,7 @@ class OCVObject(ObjectDescription): """Description of a C++ language object.""" langname = "C++" + ismember = False doc_field_types = [ TypedField('parameter', label=l_('Parameters'), @@ -1111,9 +1112,11 @@ class OCVObject(ObjectDescription): node += pnode def attach_modifiers(self, node, obj): - lname = self.__class__.langname - node += nodes.strong(lname + ":", lname + ":") - node += addnodes.desc_name(" ", " ") + if not self.__class__.ismember: + lname = self.__class__.langname + node += nodes.strong(lname + ":", lname + ":") + node += addnodes.desc_name(" ", " ") + if obj.visibility != 'public': node += addnodes.desc_annotation(obj.visibility, obj.visibility) @@ -1189,6 +1192,20 @@ class OCVClassObject(OCVObject): #self.attach_name(signode, cls.name) pass +class OCVStructObject(OCVObject): + + def get_index_text(self, name): + return _('%s (C structure)') % name + + def parse_definition(self, parser): + return parser.parse_class() + + def describe_signature(self, signode, cls): + #self.attach_modifiers(signode, cls) + #signode += addnodes.desc_annotation('class ', 'class ') + #self.attach_name(signode, cls.name) + pass + class OCVTypeObject(OCVObject): @@ -1211,6 +1228,8 @@ class OCVTypeObject(OCVObject): class OCVMemberObject(OCVObject): + ismember = True + def get_index_text(self, name): if self.objtype == 'member': return _('%s (C++ member)') % name @@ -1268,6 +1287,8 @@ class OCVFunctionObject(OCVObject): def get_index_text(self, name): lname = self.__class__.langname + if lname == "C" and name.startswith("cv"): + name = name[2:] return _('%s (%s function)') % (name, lname) def parse_definition(self, parser): @@ -1344,6 +1365,7 @@ class OCVDomain(Domain): label = 'C++' object_types = { 'class': ObjType(l_('class'), 'class'), + 'struct': ObjType(l_('struct'), 'struct'), 'function': ObjType(l_('function'), 'func', 'funcx'), 'cfunction': ObjType(l_('cfunction'), 'cfunc', 'cfuncx'), 'jfunction': ObjType(l_('jfunction'), 'jfunc', 'jfuncx'), @@ -1355,6 +1377,7 @@ class OCVDomain(Domain): directives = { 'class': OCVClassObject, + 'struct': OCVStructObject, 'function': OCVFunctionObject, 'cfunction': OCVCFunctionObject, 'jfunction': OCVJavaFunctionObject, @@ -1366,6 +1389,7 @@ class OCVDomain(Domain): } roles = { 'class': OCVXRefRole(), + 'struct': OCVXRefRole(), 'func' : OCVXRefRole(fix_parens=True), 'funcx' : OCVXRefRole(), 'cfunc' : OCVXRefRole(fix_parens=True), diff --git a/doc/opencv1/bibliography.rst b/doc/opencv1/bibliography.rst deleted file mode 100644 index 8ace6904fb..0000000000 --- a/doc/opencv1/bibliography.rst +++ /dev/null @@ -1,22 +0,0 @@ -############ -Bibliography -############ - -.. [Agrawal08] Agrawal, M. and Konolige, K. and Blas, M.R. "CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching", ECCV08, 2008 - -.. [BT96] Tomasi, C. and Birchfield, S.T. "Depth Discontinuities by Pixel-to-Pixel Stereo", STAN-CS, 1996 - -.. [Bay06] Bay, H. and Tuytelaars, T. and Van Gool, L. "SURF: Speeded Up Robust Features", 9th European Conference on Computer Vision, 2006 - -.. [Borgefors86] Borgefors, Gunilla, "Distance transformations in digital images". Comput. Vision Graph. Image Process. 34 3, pp 344--371 (1986) - -.. [Bradski00] Davis, J.W. and Bradski, G.R. "Motion Segmentation and Pose Recognition with Motion History Gradients", WACV00, 2000 - -.. [Bradski98] Bradski, G.R. "Computer Vision Face Tracking for Use in a Perceptual User Interface", Intel, 1998 - -.. [Davis97] Davis, J.W. and Bobick, A.F. "The Representation and Recognition of Action Using Temporal Templates", CVPR97, 1997 - -.. [Felzenszwalb04] Felzenszwalb, Pedro F. and Huttenlocher, Daniel P. "Distance Transforms of Sampled Functions", TR2004-1963, TR2004-1963 (2004) - -.. [Hartley99] Hartley, R.I., "Theory and Practice of Projective Rectification". IJCV 35 2, pp 115-127 (1999) - diff --git a/doc/opencv1/c/c_index.rst b/doc/opencv1/c/c_index.rst deleted file mode 100644 index e430d0cb0f..0000000000 --- a/doc/opencv1/c/c_index.rst +++ /dev/null @@ -1,16 +0,0 @@ -########################## -OpenCV 1.x C API Reference -########################## - -.. highlight:: python - -.. toctree:: - :maxdepth: 2 - - core - imgproc - features2d - objdetect - video - highgui - calib3d diff --git a/doc/opencv1/c/calib3d.rst b/doc/opencv1/c/calib3d.rst deleted file mode 100644 index 5dcd6768de..0000000000 --- a/doc/opencv1/c/calib3d.rst +++ /dev/null @@ -1,10 +0,0 @@ -******************************************************* -calib3d. Camera Calibration, Pose Estimation and Stereo -******************************************************* - - - -.. toctree:: - :maxdepth: 2 - - calib3d_camera_calibration_and_3d_reconstruction diff --git a/doc/opencv1/c/calib3d_camera_calibration_and_3d_reconstruction.rst b/doc/opencv1/c/calib3d_camera_calibration_and_3d_reconstruction.rst deleted file mode 100644 index 28f88bd291..0000000000 --- a/doc/opencv1/c/calib3d_camera_calibration_and_3d_reconstruction.rst +++ /dev/null @@ -1,2609 +0,0 @@ -Camera Calibration and 3d Reconstruction -======================================== - -.. highlight:: c - - -The functions in this section use the so-called pinhole camera model. That -is, a scene view is formed by projecting 3D points into the image plane -using a perspective transformation. - - - -.. math:: - - s \; m' = A [R|t] M' - - -or - - - -.. math:: - - s \vecthree{u}{v}{1} = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1} \begin{bmatrix} r_{11} & r_{12} & r_{13} & t_1 \\ r_{21} & r_{22} & r_{23} & t_2 \\ r_{31} & r_{32} & r_{33} & t_3 \end{bmatrix} \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix} - - -Where -:math:`(X, Y, Z)` -are the coordinates of a 3D point in the world -coordinate space, -:math:`(u, v)` -are the coordinates of the projection point -in pixels. -:math:`A` -is called a camera matrix, or a matrix of -intrinsic parameters. -:math:`(cx, cy)` -is a principal point (that is -usually at the image center), and -:math:`fx, fy` -are the focal lengths -expressed in pixel-related units. Thus, if an image from camera is -scaled by some factor, all of these parameters should -be scaled (multiplied/divided, respectively) by the same factor. The -matrix of intrinsic parameters does not depend on the scene viewed and, -once estimated, can be re-used (as long as the focal length is fixed (in -case of zoom lens)). The joint rotation-translation matrix -:math:`[R|t]` -is called a matrix of extrinsic parameters. It is used to describe the -camera motion around a static scene, or vice versa, rigid motion of an -object in front of still camera. That is, -:math:`[R|t]` -translates -coordinates of a point -:math:`(X, Y, Z)` -to some coordinate system, -fixed with respect to the camera. The transformation above is equivalent -to the following (when -:math:`z \ne 0` -): - - - -.. math:: - - \begin{array}{l} \vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\ x' = x/z \\ y' = y/z \\ u = f_x*x' + c_x \\ v = f_y*y' + c_y \end{array} - - -Real lenses usually have some distortion, mostly -radial distortion and slight tangential distortion. So, the above model -is extended as: - - - -.. math:: - - \begin{array}{l} \vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\ x' = x/z \\ y' = y/z \\ x'' = x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + 2 p_1 x' y' + p_2(r^2 + 2 x'^2) \\ y'' = y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' \\ \text{where} \quad r^2 = x'^2 + y'^2 \\ u = f_x*x'' + c_x \\ v = f_y*y'' + c_y \end{array} - - -:math:`k_1` -, -:math:`k_2` -, -:math:`k_3` -, -:math:`k_4` -, -:math:`k_5` -, -:math:`k_6` -are radial distortion coefficients, -:math:`p_1` -, -:math:`p_2` -are tangential distortion coefficients. -Higher-order coefficients are not considered in OpenCV. In the functions below the coefficients are passed or returned as - - -.. math:: - - (k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]]) - - -vector. That is, if the vector contains 4 elements, it means that -:math:`k_3=0` -. -The distortion coefficients do not depend on the scene viewed, thus they also belong to the intrinsic camera parameters. -*And they remain the same regardless of the captured image resolution.* -That is, if, for example, a camera has been calibrated on images of -:math:`320 -\times 240` -resolution, absolutely the same distortion coefficients can -be used for images of -:math:`640 \times 480` -resolution from the same camera (while -:math:`f_x` -, -:math:`f_y` -, -:math:`c_x` -and -:math:`c_y` -need to be scaled appropriately). - -The functions below use the above model to - - - - - -* - Project 3D points to the image plane given intrinsic and extrinsic parameters - - - -* - Compute extrinsic parameters given intrinsic parameters, a few 3D points and their projections. - - - -* - Estimate intrinsic and extrinsic camera parameters from several views of a known calibration pattern (i.e. every view is described by several 3D-2D point correspondences). - - - -* - Estimate the relative position and orientation of the stereo camera "heads" and compute the - *rectification* - transformation that makes the camera optical axes parallel. - - - -.. index:: CalcImageHomography - -.. _CalcImageHomography: - -CalcImageHomography -------------------- - - - - - - -.. cfunction:: void cvCalcImageHomography( float* line, CvPoint3D32f* center, float* intrinsic, float* homography ) - - Calculates the homography matrix for an oblong planar object (e.g. arm). - - - - - - - :param line: the main object axis direction (vector (dx,dy,dz)) - - - :param center: object center ((cx,cy,cz)) - - - :param intrinsic: intrinsic camera parameters (3x3 matrix) - - - :param homography: output homography matrix (3x3) - - - -The function calculates the homography -matrix for the initial image transformation from image plane to the -plane, defined by a 3D oblong object line (See -_ -_ -Figure 6-10 -_ -_ -in the OpenCV Guide 3D Reconstruction Chapter). - - -.. index:: CalibrateCamera2 - -.. _CalibrateCamera2: - -CalibrateCamera2 ----------------- - - - - - - -.. cfunction:: double cvCalibrateCamera2( const CvMat* objectPoints, const CvMat* imagePoints, const CvMat* pointCounts, CvSize imageSize, CvMat* cameraMatrix, CvMat* distCoeffs, CvMat* rvecs=NULL, CvMat* tvecs=NULL, int flags=0 ) - - Finds the camera intrinsic and extrinsic parameters from several views of a calibration pattern. - - - - - - - :param objectPoints: The joint matrix of object points - calibration pattern features in the model coordinate space. It is floating-point 3xN or Nx3 1-channel, or 1xN or Nx1 3-channel array, where N is the total number of points in all views. - - - :param imagePoints: The joint matrix of object points projections in the camera views. It is floating-point 2xN or Nx2 1-channel, or 1xN or Nx1 2-channel array, where N is the total number of points in all views - - - :param pointCounts: Integer 1xM or Mx1 vector (where M is the number of calibration pattern views) containing the number of points in each particular view. The sum of vector elements must match the size of ``objectPoints`` and ``imagePoints`` (=N). - - - :param imageSize: Size of the image, used only to initialize the intrinsic camera matrix - - - :param cameraMatrix: The output 3x3 floating-point camera matrix :math:`A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` . If ``CV_CALIB_USE_INTRINSIC_GUESS`` and/or ``CV_CALIB_FIX_ASPECT_RATIO`` are specified, some or all of ``fx, fy, cx, cy`` must be initialized before calling the function - - - :param distCoeffs: The output vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements - - - :param rvecs: The output 3x *M* or *M* x3 1-channel, or 1x *M* or *M* x1 3-channel array of rotation vectors (see :ref:`Rodrigues2` ), estimated for each pattern view. That is, each k-th rotation vector together with the corresponding k-th translation vector (see the next output parameter description) brings the calibration pattern from the model coordinate space (in which object points are specified) to the world coordinate space, i.e. real position of the calibration pattern in the k-th pattern view (k=0.. *M* -1) - - - :param tvecs: The output 3x *M* or *M* x3 1-channel, or 1x *M* or *M* x1 3-channel array of translation vectors, estimated for each pattern view. - - - :param flags: Different flags, may be 0 or combination of the following values: - - * **CV_CALIB_USE_INTRINSIC_GUESS** ``cameraMatrix`` contains the valid initial values of ``fx, fy, cx, cy`` that are optimized further. Otherwise, ``(cx, cy)`` is initially set to the image center ( ``imageSize`` is used here), and focal distances are computed in some least-squares fashion. Note, that if intrinsic parameters are known, there is no need to use this function just to estimate the extrinsic parameters. Use :ref:`FindExtrinsicCameraParams2` instead. - - * **CV_CALIB_FIX_PRINCIPAL_POINT** The principal point is not changed during the global optimization, it stays at the center or at the other location specified when ``CV_CALIB_USE_INTRINSIC_GUESS`` is set too. - - * **CV_CALIB_FIX_ASPECT_RATIO** The functions considers only ``fy`` as a free parameter, the ratio ``fx/fy`` stays the same as in the input ``cameraMatrix`` . When ``CV_CALIB_USE_INTRINSIC_GUESS`` is not set, the actual input values of ``fx`` and ``fy`` are ignored, only their ratio is computed and used further. - - * **CV_CALIB_ZERO_TANGENT_DIST** Tangential distortion coefficients :math:`(p_1, p_2)` will be set to zeros and stay zero. - - - - * **CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6** Do not change the corresponding radial distortion coefficient during the optimization. If ``CV_CALIB_USE_INTRINSIC_GUESS`` is set, the coefficient from the supplied ``distCoeffs`` matrix is used, otherwise it is set to 0. - - - * **CV_CALIB_RATIONAL_MODEL** Enable coefficients k4, k5 and k6. To provide the backward compatibility, this extra flag should be explicitly specified to make the calibration function use the rational model and return 8 coefficients. If the flag is not set, the function will compute only 5 distortion coefficients. - - - - - -The function estimates the intrinsic camera -parameters and extrinsic parameters for each of the views. The -coordinates of 3D object points and their correspondent 2D projections -in each view must be specified. That may be achieved by using an -object with known geometry and easily detectable feature points. -Such an object is called a calibration rig or calibration pattern, -and OpenCV has built-in support for a chessboard as a calibration -rig (see -:ref:`FindChessboardCorners` -). Currently, initialization -of intrinsic parameters (when -``CV_CALIB_USE_INTRINSIC_GUESS`` -is not set) is only implemented for planar calibration patterns -(where z-coordinates of the object points must be all 0's). 3D -calibration rigs can also be used as long as initial -``cameraMatrix`` -is provided. - -The algorithm does the following: - - - - -#. - First, it computes the initial intrinsic parameters (the option only available for planar calibration patterns) or reads them from the input parameters. The distortion coefficients are all set to zeros initially (unless some of - ``CV_CALIB_FIX_K?`` - are specified). - - - -#. - The initial camera pose is estimated as if the intrinsic parameters have been already known. This is done using - :ref:`FindExtrinsicCameraParams2` - - -#. - After that the global Levenberg-Marquardt optimization algorithm is run to minimize the reprojection error, i.e. the total sum of squared distances between the observed feature points - ``imagePoints`` - and the projected (using the current estimates for camera parameters and the poses) object points - ``objectPoints`` - ; see - :ref:`ProjectPoints2` - . - - -The function returns the final re-projection error. -Note: if you're using a non-square (=non-NxN) grid and -:cpp:func:`findChessboardCorners` -for calibration, and -``calibrateCamera`` -returns -bad values (i.e. zero distortion coefficients, an image center very far from -:math:`(w/2-0.5,h/2-0.5)` -, and / or large differences between -:math:`f_x` -and -:math:`f_y` -(ratios of -10:1 or more)), then you've probably used -``patternSize=cvSize(rows,cols)`` -, -but should use -``patternSize=cvSize(cols,rows)`` -in -:ref:`FindChessboardCorners` -. - -See also: -:ref:`FindChessboardCorners` -, -:ref:`FindExtrinsicCameraParams2` -, -:cpp:func:`initCameraMatrix2D` -, -:ref:`StereoCalibrate` -, -:ref:`Undistort2` - -.. index:: ComputeCorrespondEpilines - -.. _ComputeCorrespondEpilines: - -ComputeCorrespondEpilines -------------------------- - - - - - - -.. cfunction:: void cvComputeCorrespondEpilines( const CvMat* points, int whichImage, const CvMat* F, CvMat* lines) - - For points in one image of a stereo pair, computes the corresponding epilines in the other image. - - - - - - - :param points: The input points. ``2xN, Nx2, 3xN`` or ``Nx3`` array (where ``N`` number of points). Multi-channel ``1xN`` or ``Nx1`` array is also acceptable - - - :param whichImage: Index of the image (1 or 2) that contains the ``points`` - - - :param F: The fundamental matrix that can be estimated using :ref:`FindFundamentalMat` - or :ref:`StereoRectify` . - - - :param lines: The output epilines, a ``3xN`` or ``Nx3`` array. Each line :math:`ax + by + c=0` is encoded by 3 numbers :math:`(a, b, c)` - - - -For every point in one of the two images of a stereo-pair the function finds the equation of the -corresponding epipolar line in the other image. - -From the fundamental matrix definition (see -:ref:`FindFundamentalMat` -), -line -:math:`l^{(2)}_i` -in the second image for the point -:math:`p^{(1)}_i` -in the first image (i.e. when -``whichImage=1`` -) is computed as: - - - -.. math:: - - l^{(2)}_i = F p^{(1)}_i - - -and, vice versa, when -``whichImage=2`` -, -:math:`l^{(1)}_i` -is computed from -:math:`p^{(2)}_i` -as: - - - -.. math:: - - l^{(1)}_i = F^T p^{(2)}_i - - -Line coefficients are defined up to a scale. They are normalized, such that -:math:`a_i^2+b_i^2=1` -. - - -.. index:: ConvertPointsHomogeneous - -.. _ConvertPointsHomogeneous: - -ConvertPointsHomogeneous ------------------------- - - - - - - -.. cfunction:: void cvConvertPointsHomogeneous( const CvMat* src, CvMat* dst ) - - Convert points to/from homogeneous coordinates. - - - - - - - :param src: The input point array, ``2xN, Nx2, 3xN, Nx3, 4xN or Nx4 (where ``N`` is the number of points)`` . Multi-channel ``1xN`` or ``Nx1`` array is also acceptable - - - :param dst: The output point array, must contain the same number of points as the input; The dimensionality must be the same, 1 less or 1 more than the input, and also within 2 to 4 - - - -The -function converts -2D or 3D points from/to homogeneous coordinates, or simply -copies or transposes -the array. If the input array dimensionality is larger than the output, each coordinate is divided by the last coordinate: - - - -.. math:: - - \begin{array}{l} (x,y[,z],w) -> (x',y'[,z']) \\ \text{where} \\ x' = x/w \\ y' = y/w \\ z' = z/w \quad \text{(if output is 3D)} \end{array} - - -If the output array dimensionality is larger, an extra 1 is appended to each point. Otherwise, the input array is simply copied (with optional transposition) to the output. - -**Note** because the function accepts a large variety of array layouts, it may report an error when input/output array dimensionality is ambiguous. It is always safe to use the function with number of points :math:`\texttt{N} \ge 5` , or to use multi-channel ``Nx1`` or ``1xN`` arrays. - -.. index:: CreatePOSITObject - -.. _CreatePOSITObject: - -CreatePOSITObject ------------------ - - - - - - -.. cfunction:: CvPOSITObject* cvCreatePOSITObject( CvPoint3D32f* points, int point_count ) - - Initializes a structure containing object information. - - - - - - - :param points: Pointer to the points of the 3D object model - - - :param point_count: Number of object points - - - -The function allocates memory for the object structure and computes the object inverse matrix. - -The preprocessed object data is stored in the structure -:ref:`CvPOSITObject` -, internal for OpenCV, which means that the user cannot directly access the structure data. The user may only create this structure and pass its pointer to the function. - -An object is defined as a set of points given in a coordinate system. The function -:ref:`POSIT` -computes a vector that begins at a camera-related coordinate system center and ends at the -``points[0]`` -of the object. - -Once the work with a given object is finished, the function -:ref:`ReleasePOSITObject` -must be called to free memory. - - -.. index:: CreateStereoBMState - -.. _CreateStereoBMState: - -CreateStereoBMState -------------------- - - - - - - -.. cfunction:: CvStereoBMState* cvCreateStereoBMState( int preset=CV_STEREO_BM_BASIC, int numberOfDisparities=0 ) - - Creates block matching stereo correspondence structure. - - - - - - - :param preset: ID of one of the pre-defined parameter sets. Any of the parameters can be overridden after creating the structure. Values are - - * **CV_STEREO_BM_BASIC** Parameters suitable for general cameras - - * **CV_STEREO_BM_FISH_EYE** Parameters suitable for wide-angle cameras - - * **CV_STEREO_BM_NARROW** Parameters suitable for narrow-angle cameras - - - - - :param numberOfDisparities: The number of disparities. If the parameter is 0, it is taken from the preset, otherwise the supplied value overrides the one from preset. - - - -The function creates the stereo correspondence structure and initializes -it. It is possible to override any of the parameters at any time between -the calls to -:ref:`FindStereoCorrespondenceBM` -. - - -.. index:: CreateStereoGCState - -.. _CreateStereoGCState: - -CreateStereoGCState -------------------- - - - - - - -.. cfunction:: CvStereoGCState* cvCreateStereoGCState( int numberOfDisparities, int maxIters ) - - Creates the state of graph cut-based stereo correspondence algorithm. - - - - - - - :param numberOfDisparities: The number of disparities. The disparity search range will be :math:`\texttt{state->minDisparity} \le disparity < \texttt{state->minDisparity} + \texttt{state->numberOfDisparities}` - - - :param maxIters: Maximum number of iterations. On each iteration all possible (or reasonable) alpha-expansions are tried. The algorithm may terminate earlier if it could not find an alpha-expansion that decreases the overall cost function value. See Kolmogorov03 for details. - - - -The function creates the stereo correspondence structure and initializes it. It is possible to override any of the parameters at any time between the calls to -:ref:`FindStereoCorrespondenceGC` -. - - -.. index:: CvStereoBMState - -.. _CvStereoBMState: - -CvStereoBMState ---------------- - - - -.. ctype:: CvStereoBMState - - - -The structure for block matching stereo correspondence algorithm. - - - - -:: - - - - typedef struct CvStereoBMState - { - //pre filters (normalize input images): - int preFilterType; // 0 for now - int preFilterSize; // ~5x5..21x21 - int preFilterCap; // up to ~31 - //correspondence using Sum of Absolute Difference (SAD): - int SADWindowSize; // Could be 5x5..21x21 - int minDisparity; // minimum disparity (=0) - int numberOfDisparities; // maximum disparity - minimum disparity - //post filters (knock out bad matches): - int textureThreshold; // areas with no texture are ignored - int uniquenessRatio;// invalidate disparity at pixels where there are other close matches - // with different disparity - int speckleWindowSize; // the maximum area of speckles to remove - // (set to 0 to disable speckle filtering) - int speckleRange; // acceptable range of disparity variation in each connected component - - int trySmallerWindows; // not used - CvRect roi1, roi2; // clipping ROIs - - int disp12MaxDiff; // maximum allowed disparity difference in the left-right check - - // internal data - ... - } - CvStereoBMState; - - -.. - - - - - - .. attribute:: preFilterType - - - - type of the prefilter, ``CV_STEREO_BM_NORMALIZED_RESPONSE`` or the default and the recommended ``CV_STEREO_BM_XSOBEL`` , int - - - - .. attribute:: preFilterSize - - - - ~5x5..21x21, int - - - - .. attribute:: preFilterCap - - - - up to ~31, int - - - - .. attribute:: SADWindowSize - - - - Could be 5x5..21x21 or higher, but with 21x21 or smaller windows the processing speed is much higher, int - - - - .. attribute:: minDisparity - - - - minimum disparity (=0), int - - - - .. attribute:: numberOfDisparities - - - - maximum disparity - minimum disparity, int - - - - .. attribute:: textureThreshold - - - - the textureness threshold. That is, if the sum of absolute values of x-derivatives computed over ``SADWindowSize`` by ``SADWindowSize`` pixel neighborhood is smaller than the parameter, no disparity is computed at the pixel, int - - - - .. attribute:: uniquenessRatio - - - - the minimum margin in percents between the best (minimum) cost function value and the second best value to accept the computed disparity, int - - - - .. attribute:: speckleWindowSize - - - - the maximum area of speckles to remove (set to 0 to disable speckle filtering), int - - - - .. attribute:: speckleRange - - - - acceptable range of disparity variation in each connected component, int - - - - .. attribute:: trySmallerWindows - - - - not used currently (0), int - - - - .. attribute:: roi1, roi2 - - - - These are the clipping ROIs for the left and the right images. The function :ref:`StereoRectify` returns the largest rectangles in the left and right images where after the rectification all the pixels are valid. If you copy those rectangles to the ``CvStereoBMState`` structure, the stereo correspondence function will automatically clear out the pixels outside of the "valid" disparity rectangle computed by :ref:`GetValidDisparityROI` . Thus you will get more "invalid disparity" pixels than usual, but the remaining pixels are more probable to be valid. - - - - .. attribute:: disp12MaxDiff - - - - The maximum allowed difference between the explicitly computed left-to-right disparity map and the implicitly (by :ref:`ValidateDisparity` ) computed right-to-left disparity. If for some pixel the difference is larger than the specified threshold, the disparity at the pixel is invalidated. By default this parameter is set to (-1), which means that the left-right check is not performed. - - - -The block matching stereo correspondence algorithm, by Kurt Konolige, is very fast single-pass stereo matching algorithm that uses sliding sums of absolute differences between pixels in the left image and the pixels in the right image, shifted by some varying amount of pixels (from -``minDisparity`` -to -``minDisparity+numberOfDisparities`` -). On a pair of images WxH the algorithm computes disparity in -``O(W*H*numberOfDisparities)`` -time. In order to improve quality and readability of the disparity map, the algorithm includes pre-filtering and post-filtering procedures. - -Note that the algorithm searches for the corresponding blocks in x direction only. It means that the supplied stereo pair should be rectified. Vertical stereo layout is not directly supported, but in such a case the images could be transposed by user. - - -.. index:: CvStereoGCState - -.. _CvStereoGCState: - -CvStereoGCState ---------------- - - - -.. ctype:: CvStereoGCState - - - -The structure for graph cuts-based stereo correspondence algorithm - - - - -:: - - - - typedef struct CvStereoGCState - { - int Ithreshold; // threshold for piece-wise linear data cost function (5 by default) - int interactionRadius; // radius for smoothness cost function (1 by default; means Potts model) - float K, lambda, lambda1, lambda2; // parameters for the cost function - // (usually computed adaptively from the input data) - int occlusionCost; // 10000 by default - int minDisparity; // 0 by default; see CvStereoBMState - int numberOfDisparities; // defined by user; see CvStereoBMState - int maxIters; // number of iterations; defined by user. - - // internal buffers - CvMat* left; - CvMat* right; - CvMat* dispLeft; - CvMat* dispRight; - CvMat* ptrLeft; - CvMat* ptrRight; - CvMat* vtxBuf; - CvMat* edgeBuf; - } - CvStereoGCState; - - -.. - -The graph cuts stereo correspondence algorithm, described in -Kolmogorov03 -(as -**KZ1** -), is non-realtime stereo correspondence algorithm that usually gives very accurate depth map with well-defined object boundaries. The algorithm represents stereo problem as a sequence of binary optimization problems, each of those is solved using maximum graph flow algorithm. The state structure above should not be allocated and initialized manually; instead, use -:ref:`CreateStereoGCState` -and then override necessary parameters if needed. - - -.. index:: DecomposeProjectionMatrix - -.. _DecomposeProjectionMatrix: - -DecomposeProjectionMatrix -------------------------- - - - - - - -.. cfunction:: void cvDecomposeProjectionMatrix( const CvMat *projMatrix, CvMat *cameraMatrix, CvMat *rotMatrix, CvMat *transVect, CvMat *rotMatrX=NULL, CvMat *rotMatrY=NULL, CvMat *rotMatrZ=NULL, CvPoint3D64f *eulerAngles=NULL) - - Decomposes the projection matrix into a rotation matrix and a camera matrix. - - - - - - - :param projMatrix: The 3x4 input projection matrix P - - - :param cameraMatrix: The output 3x3 camera matrix K - - - :param rotMatrix: The output 3x3 external rotation matrix R - - - :param transVect: The output 4x1 translation vector T - - - :param rotMatrX: Optional 3x3 rotation matrix around x-axis - - - :param rotMatrY: Optional 3x3 rotation matrix around y-axis - - - :param rotMatrZ: Optional 3x3 rotation matrix around z-axis - - - :param eulerAngles: Optional 3 points containing the three Euler angles of rotation - - - -The function computes a decomposition of a projection matrix into a calibration and a rotation matrix and the position of the camera. - -It optionally returns three rotation matrices, one for each axis, and the three Euler angles that could be used in OpenGL. - -The function is based on -:ref:`RQDecomp3x3` -. - - -.. index:: DrawChessboardCorners - -.. _DrawChessboardCorners: - -DrawChessboardCorners ---------------------- - - - - - - -.. cfunction:: void cvDrawChessboardCorners( CvArr* image, CvSize patternSize, CvPoint2D32f* corners, int count, int patternWasFound ) - - Renders the detected chessboard corners. - - - - - - - :param image: The destination image; it must be an 8-bit color image - - - :param patternSize: The number of inner corners per chessboard row and column. (patternSize = cv::Size(points _ per _ row,points _ per _ column) = cv::Size(rows,columns) ) - - - :param corners: The array of corners detected, this should be the output from findChessboardCorners wrapped in a cv::Mat(). - - - :param count: The number of corners - - - :param patternWasFound: Indicates whether the complete board was found :math:`(\ne 0)` or not :math:`(=0)` . One may just pass the return value :ref:`FindChessboardCorners` here - - - -The function draws the individual chessboard corners detected as red circles if the board was not found or as colored corners connected with lines if the board was found. - - -.. index:: FindChessboardCorners - -.. _FindChessboardCorners: - -FindChessboardCorners ---------------------- - - - - - - -.. cfunction:: int cvFindChessboardCorners( const void* image, CvSize patternSize, CvPoint2D32f* corners, int* cornerCount=NULL, int flags=CV_CALIB_CB_ADAPTIVE_THRESH ) - - Finds the positions of the internal corners of the chessboard. - - - - - - - :param image: Source chessboard view; it must be an 8-bit grayscale or color image - - - :param patternSize: The number of inner corners per chessboard row and column - ( patternSize = cvSize(points _ per _ row,points _ per _ colum) = cvSize(columns,rows) ) - - - :param corners: The output array of corners detected - - - :param cornerCount: The output corner counter. If it is not NULL, it stores the number of corners found - - - :param flags: Various operation flags, can be 0 or a combination of the following values: - - - * **CV_CALIB_CB_ADAPTIVE_THRESH** use adaptive thresholding to convert the image to black and white, rather than a fixed threshold level (computed from the average image brightness). - - - * **CV_CALIB_CB_NORMALIZE_IMAGE** normalize the image gamma with :ref:`EqualizeHist` before applying fixed or adaptive thresholding. - - - * **CV_CALIB_CB_FILTER_QUADS** use additional criteria (like contour area, perimeter, square-like shape) to filter out false quads that are extracted at the contour retrieval stage. - - - * **CALIB_CB_FAST_CHECK** Runs a fast check on the image that looks for chessboard corners, and shortcuts the call if none are found. This can drastically speed up the call in the degenerate condition when - no chessboard is observed. - - - - - -The function attempts to determine -whether the input image is a view of the chessboard pattern and -locate the internal chessboard corners. The function returns a non-zero -value if all of the corners have been found and they have been placed -in a certain order (row by row, left to right in every row), -otherwise, if the function fails to find all the corners or reorder -them, it returns 0. For example, a regular chessboard has 8 x 8 -squares and 7 x 7 internal corners, that is, points, where the black -squares touch each other. The coordinates detected are approximate, -and to determine their position more accurately, the user may use -the function -:ref:`FindCornerSubPix` -. - -Sample usage of detecting and drawing chessboard corners: - - - -:: - - - - Size patternsize(8,6); //interior number of corners - Mat gray = ....; //source image - vector corners; //this will be filled by the detected corners - - //CALIB_CB_FAST_CHECK saves a lot of time on images - //that don't contain any chessboard corners - bool patternfound = findChessboardCorners(gray, patternsize, corners, - CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE - + CALIB_CB_FAST_CHECK); - - if(patternfound) - cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1), - TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1)); - - drawChessboardCorners(img, patternsize, Mat(corners), patternfound); - - -.. - -**Note:** -the function requires some white space (like a square-thick border, the wider the better) around the board to make the detection more robust in various environment (otherwise if there is no border and the background is dark, the outer black squares could not be segmented properly and so the square grouping and ordering algorithm will fail). - - -.. index:: FindExtrinsicCameraParams2 - -.. _FindExtrinsicCameraParams2: - -FindExtrinsicCameraParams2 --------------------------- - - - - - - -.. cfunction:: void cvFindExtrinsicCameraParams2( const CvMat* objectPoints, const CvMat* imagePoints, const CvMat* cameraMatrix, const CvMat* distCoeffs, CvMat* rvec, CvMat* tvec, int useExtrinsicGuess=0) - - Finds the object pose from the 3D-2D point correspondences - - - - - - - :param objectPoints: The array of object points in the object coordinate space, 3xN or Nx3 1-channel, or 1xN or Nx1 3-channel, where N is the number of points. - - - :param imagePoints: The array of corresponding image points, 2xN or Nx2 1-channel or 1xN or Nx1 2-channel, where N is the number of points. - - - :param cameraMatrix: The input camera matrix :math:`A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - - :param rvec: The output rotation vector (see :ref:`Rodrigues2` ) that (together with ``tvec`` ) brings points from the model coordinate system to the camera coordinate system - - - :param tvec: The output translation vector - - - :param useExtrinsicGuess: If true (1), the function will use the provided ``rvec`` and ``tvec`` as the initial approximations of the rotation and translation vectors, respectively, and will further optimize them. - - - -The function estimates the object pose given a set of object points, their corresponding image projections, as well as the camera matrix and the distortion coefficients. This function finds such a pose that minimizes reprojection error, i.e. the sum of squared distances between the observed projections -``imagePoints`` -and the projected (using -:ref:`ProjectPoints2` -) -``objectPoints`` -. - - -The function's counterpart in the C++ API is - -.. index:: FindFundamentalMat - -.. _FindFundamentalMat: - -FindFundamentalMat ------------------- - - - - - - -.. cfunction:: int cvFindFundamentalMat( const CvMat* points1, const CvMat* points2, CvMat* fundamentalMatrix, int method=CV_FM_RANSAC, double param1=1., double param2=0.99, CvMat* status=NULL) - - Calculates the fundamental matrix from the corresponding points in two images. - - - - - - - :param points1: Array of ``N`` points from the first image. It can be ``2xN, Nx2, 3xN`` or ``Nx3`` 1-channel array or ``1xN`` or ``Nx1`` 2- or 3-channel array . The point coordinates should be floating-point (single or double precision) - - - :param points2: Array of the second image points of the same size and format as ``points1`` - - - :param fundamentalMatrix: The output fundamental matrix or matrices. The size should be 3x3 or 9x3 (7-point method may return up to 3 matrices) - - - :param method: Method for computing the fundamental matrix - - - * **CV_FM_7POINT** for a 7-point algorithm. :math:`N = 7` - - - * **CV_FM_8POINT** for an 8-point algorithm. :math:`N \ge 8` - - - * **CV_FM_RANSAC** for the RANSAC algorithm. :math:`N \ge 8` - - - * **CV_FM_LMEDS** for the LMedS algorithm. :math:`N \ge 8` - - - - - :param param1: The parameter is used for RANSAC. It is the maximum distance from point to epipolar line in pixels, beyond which the point is considered an outlier and is not used for computing the final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the point localization, image resolution and the image noise - - - :param param2: The parameter is used for RANSAC or LMedS methods only. It specifies the desirable level of confidence (probability) that the estimated matrix is correct - - - :param status: The optional output array of N elements, every element of which is set to 0 for outliers and to 1 for the other points. The array is computed only in RANSAC and LMedS methods. For other methods it is set to all 1's - - - -The epipolar geometry is described by the following equation: - - - -.. math:: - - [p_2; 1]^T F [p_1; 1] = 0 - - -where -:math:`F` -is fundamental matrix, -:math:`p_1` -and -:math:`p_2` -are corresponding points in the first and the second images, respectively. - -The function calculates the fundamental matrix using one of four methods listed above and returns -the number of fundamental matrices found (1 or 3) and 0, if no matrix is found -. Normally just 1 matrix is found, but in the case of 7-point algorithm the function may return up to 3 solutions ( -:math:`9 \times 3` -matrix that stores all 3 matrices sequentially). - -The calculated fundamental matrix may be passed further to -:ref:`ComputeCorrespondEpilines` -that finds the epipolar lines -corresponding to the specified points. It can also be passed to -:ref:`StereoRectifyUncalibrated` -to compute the rectification transformation. - - - - -:: - - - - int point_count = 100; - CvMat* points1; - CvMat* points2; - CvMat* status; - CvMat* fundamental_matrix; - - points1 = cvCreateMat(1,point_count,CV_32FC2); - points2 = cvCreateMat(1,point_count,CV_32FC2); - status = cvCreateMat(1,point_count,CV_8UC1); - - /* Fill the points here ... */ - for( i = 0; i < point_count; i++ ) - { - points1->data.fl[i*2] = ; - points1->data.fl[i*2+1] = ; - points2->data.fl[i*2] = ; - points2->data.fl[i*2+1] = ; - } - - fundamental_matrix = cvCreateMat(3,3,CV_32FC1); - int fm_count = cvFindFundamentalMat( points1,points2,fundamental_matrix, - CV_FM_RANSAC,1.0,0.99,status ); - - -.. - - -.. index:: FindHomography - -.. _FindHomography: - -FindHomography --------------- - - - - - - -.. cfunction:: void cvFindHomography( const CvMat* srcPoints, const CvMat* dstPoints, CvMat* H int method=0, double ransacReprojThreshold=3, CvMat* status=NULL) - - Finds the perspective transformation between two planes. - - - - - - - :param srcPoints: Coordinates of the points in the original plane, 2xN, Nx2, 3xN or Nx3 1-channel array (the latter two are for representation in homogeneous coordinates), where N is the number of points. 1xN or Nx1 2- or 3-channel array can also be passed. - - :param dstPoints: Point coordinates in the destination plane, 2xN, Nx2, 3xN or Nx3 1-channel, or 1xN or Nx1 2- or 3-channel array. - - - :param H: The output 3x3 homography matrix - - - :param method: The method used to computed homography matrix; one of the following: - - * **0** a regular method using all the points - - * **CV_RANSAC** RANSAC-based robust method - - * **CV_LMEDS** Least-Median robust method - - - - - :param ransacReprojThreshold: The maximum allowed reprojection error to treat a point pair as an inlier (used in the RANSAC method only). That is, if - - .. math:: - - \| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} \texttt{srcPoints} _i) \| > \texttt{ransacReprojThreshold} - - then the point :math:`i` is considered an outlier. If ``srcPoints`` and ``dstPoints`` are measured in pixels, it usually makes sense to set this parameter somewhere in the range 1 to 10. - - - :param status: The optional output mask set by a robust method ( ``CV_RANSAC`` or ``CV_LMEDS`` ). *Note that the input mask values are ignored.* - - - -The -function finds -the perspective transformation -:math:`H` -between the source and the destination planes: - - - -.. math:: - - s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1} - - -So that the back-projection error - - - -.. math:: - - \sum _i \left ( x'_i- \frac{h_{11} x_i + h_{12} y_i + h_{13}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2+ \left ( y'_i- \frac{h_{21} x_i + h_{22} y_i + h_{23}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2 - - -is minimized. If the parameter -``method`` -is set to the default value 0, the function -uses all the point pairs to compute the initial homography estimate with a simple least-squares scheme. - -However, if not all of the point pairs ( -:math:`srcPoints_i` -, -:math:`dstPoints_i` -) fit the rigid perspective transformation (i.e. there -are some outliers), this initial estimate will be poor. -In this case one can use one of the 2 robust methods. Both methods, -``RANSAC`` -and -``LMeDS`` -, try many different random subsets -of the corresponding point pairs (of 4 pairs each), estimate -the homography matrix using this subset and a simple least-square -algorithm and then compute the quality/goodness of the computed homography -(which is the number of inliers for RANSAC or the median re-projection -error for LMeDs). The best subset is then used to produce the initial -estimate of the homography matrix and the mask of inliers/outliers. - -Regardless of the method, robust or not, the computed homography -matrix is refined further (using inliers only in the case of a robust -method) with the Levenberg-Marquardt method in order to reduce the -re-projection error even more. - -The method -``RANSAC`` -can handle practically any ratio of outliers, -but it needs the threshold to distinguish inliers from outliers. -The method -``LMeDS`` -does not need any threshold, but it works -correctly only when there are more than 50 -% -of inliers. Finally, -if you are sure in the computed features, where can be only some -small noise present, but no outliers, the default method could be the best -choice. - -The function is used to find initial intrinsic and extrinsic matrices. -Homography matrix is determined up to a scale, thus it is normalized so that -:math:`h_{33}=1` -. - -See also: -:ref:`GetAffineTransform` -, -:ref:`GetPerspectiveTransform` -, -:ref:`EstimateRigidMotion` -, -:ref:`WarpPerspective` -, -:ref:`PerspectiveTransform` - -.. index:: FindStereoCorrespondenceBM - -.. _FindStereoCorrespondenceBM: - -FindStereoCorrespondenceBM --------------------------- - - - - - - -.. cfunction:: void cvFindStereoCorrespondenceBM( const CvArr* left, const CvArr* right, CvArr* disparity, CvStereoBMState* state ) - - Computes the disparity map using block matching algorithm. - - - - - - - :param left: The left single-channel, 8-bit image. - - - :param right: The right image of the same size and the same type. - - - :param disparity: The output single-channel 16-bit signed, or 32-bit floating-point disparity map of the same size as input images. In the first case the computed disparities are represented as fixed-point numbers with 4 fractional bits (i.e. the computed disparity values are multiplied by 16 and rounded to integers). - - - :param state: Stereo correspondence structure. - - - -The function cvFindStereoCorrespondenceBM computes disparity map for the input rectified stereo pair. Invalid pixels (for which disparity can not be computed) are set to -``state->minDisparity - 1`` -(or to -``(state->minDisparity-1)*16`` -in the case of 16-bit fixed-point disparity map) - - -.. index:: FindStereoCorrespondenceGC - -.. _FindStereoCorrespondenceGC: - -FindStereoCorrespondenceGC --------------------------- - - - - - - -.. cfunction:: void cvFindStereoCorrespondenceGC( const CvArr* left, const CvArr* right, CvArr* dispLeft, CvArr* dispRight, CvStereoGCState* state, int useDisparityGuess = CV_DEFAULT(0) ) - - Computes the disparity map using graph cut-based algorithm. - - - - - - - :param left: The left single-channel, 8-bit image. - - - :param right: The right image of the same size and the same type. - - - :param dispLeft: The optional output single-channel 16-bit signed left disparity map of the same size as input images. - - - :param dispRight: The optional output single-channel 16-bit signed right disparity map of the same size as input images. - - - :param state: Stereo correspondence structure. - - - :param useDisparityGuess: If the parameter is not zero, the algorithm will start with pre-defined disparity maps. Both dispLeft and dispRight should be valid disparity maps. Otherwise, the function starts with blank disparity maps (all pixels are marked as occlusions). - - - -The function computes disparity maps for the input rectified stereo pair. Note that the left disparity image will contain values in the following range: - - - -.. math:: - - - \texttt{state->numberOfDisparities} - \texttt{state->minDisparity} < dispLeft(x,y) \le - \texttt{state->minDisparity} , - - -or - - -.. math:: - - dispLeft(x,y) == \texttt{CV\_STEREO\_GC\_OCCLUSION} - - -and for the right disparity image the following will be true: - - - -.. math:: - - \texttt{state->minDisparity} \le dispRight(x,y) - < \texttt{state->minDisparity} + \texttt{state->numberOfDisparities} - - -or - - - -.. math:: - - dispRight(x,y) == \texttt{CV\_STEREO\_GC\_OCCLUSION} - - -that is, the range for the left disparity image will be inversed, -and the pixels for which no good match has been found, will be marked -as occlusions. - -Here is how the function can be used: - - - - -:: - - - - // image_left and image_right are the input 8-bit single-channel images - // from the left and the right cameras, respectively - CvSize size = cvGetSize(image_left); - CvMat* disparity_left = cvCreateMat( size.height, size.width, CV_16S ); - CvMat* disparity_right = cvCreateMat( size.height, size.width, CV_16S ); - CvStereoGCState* state = cvCreateStereoGCState( 16, 2 ); - cvFindStereoCorrespondenceGC( image_left, image_right, - disparity_left, disparity_right, state, 0 ); - cvReleaseStereoGCState( &state ); - // now process the computed disparity images as you want ... - - -.. - -and this is the output left disparity image computed from the well-known -Tsukuba stereo pair and multiplied by -16 (because the values in the -left disparity images are usually negative): - - - - -:: - - - - CvMat* disparity_left_visual = cvCreateMat( size.height, size.width, CV_8U ); - cvConvertScale( disparity_left, disparity_left_visual, -16 ); - cvSave( "disparity.pgm", disparity_left_visual ); - - -.. - - - -.. image:: ../pics/disparity.png - - - - -.. index:: GetOptimalNewCameraMatrix - -.. _GetOptimalNewCameraMatrix: - -GetOptimalNewCameraMatrix -------------------------- - - - - - - -.. cfunction:: void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCoeffs, CvSize imageSize, double alpha, CvMat* newCameraMatrix, CvSize newImageSize=cvSize(0,0), CvRect* validPixROI=0 ) - - Returns the new camera matrix based on the free scaling parameter - - - - - - - :param cameraMatrix: The input camera matrix - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - - :param imageSize: The original image size - - - :param alpha: The free scaling parameter between 0 (when all the pixels in the undistorted image will be valid) and 1 (when all the source image pixels will be retained in the undistorted image); see :ref:`StereoRectify` - - - :param newCameraMatrix: The output new camera matrix. - - - :param newImageSize: The image size after rectification. By default it will be set to ``imageSize`` . - - - :param validPixROI: The optional output rectangle that will outline all-good-pixels region in the undistorted image. See ``roi1, roi2`` description in :ref:`StereoRectify` - - - -The function computes -the optimal new camera matrix based on the free scaling parameter. By varying this parameter the user may retrieve only sensible pixels -``alpha=0`` -, keep all the original image pixels if there is valuable information in the corners -``alpha=1`` -, or get something in between. When -``alpha>0`` -, the undistortion result will likely have some black pixels corresponding to "virtual" pixels outside of the captured distorted image. The original camera matrix, distortion coefficients, the computed new camera matrix and the -``newImageSize`` -should be passed to -:ref:`InitUndistortRectifyMap` -to produce the maps for -:ref:`Remap` -. - - -.. index:: InitIntrinsicParams2D - -.. _InitIntrinsicParams2D: - -InitIntrinsicParams2D ---------------------- - - - - - - -.. cfunction:: void cvInitIntrinsicParams2D( const CvMat* objectPoints, const CvMat* imagePoints, const CvMat* npoints, CvSize imageSize, CvMat* cameraMatrix, double aspectRatio=1.) - - Finds the initial camera matrix from the 3D-2D point correspondences - - - - - - - :param objectPoints: The joint array of object points; see :ref:`CalibrateCamera2` - - - :param imagePoints: The joint array of object point projections; see :ref:`CalibrateCamera2` - - - :param npoints: The array of point counts; see :ref:`CalibrateCamera2` - - - :param imageSize: The image size in pixels; used to initialize the principal point - - - :param cameraMatrix: The output camera matrix :math:`\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` - - - :param aspectRatio: If it is zero or negative, both :math:`f_x` and :math:`f_y` are estimated independently. Otherwise :math:`f_x = f_y * \texttt{aspectRatio}` - - - -The function estimates and returns the initial camera matrix for camera calibration process. -Currently, the function only supports planar calibration patterns, i.e. patterns where each object point has z-coordinate =0. - - -.. index:: InitUndistortMap - -.. _InitUndistortMap: - -InitUndistortMap ----------------- - - - - - - -.. cfunction:: void cvInitUndistortMap( const CvMat* cameraMatrix, const CvMat* distCoeffs, CvArr* map1, CvArr* map2 ) - - Computes an undistortion map. - - - - - - - :param cameraMatrix: The input camera matrix :math:`A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - - :param map1: The first output map of type ``CV_32FC1`` or ``CV_16SC2`` - the second variant is more efficient - - - :param map2: The second output map of type ``CV_32FC1`` or ``CV_16UC1`` - the second variant is more efficient - - - -The function is a simplified variant of -:ref:`InitUndistortRectifyMap` -where the rectification transformation -``R`` -is identity matrix and -``newCameraMatrix=cameraMatrix`` -. - - -.. index:: InitUndistortRectifyMap - -.. _InitUndistortRectifyMap: - -InitUndistortRectifyMap ------------------------ - - - - - - -.. cfunction:: void cvInitUndistortRectifyMap( const CvMat* cameraMatrix, const CvMat* distCoeffs, const CvMat* R, const CvMat* newCameraMatrix, CvArr* map1, CvArr* map2 ) - - Computes the undistortion and rectification transformation map. - - - - - - - :param cameraMatrix: The input camera matrix :math:`A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - - :param R: The optional rectification transformation in object space (3x3 matrix). ``R1`` or ``R2`` , computed by :ref:`StereoRectify` can be passed here. If the matrix is NULL , the identity transformation is assumed - - - :param newCameraMatrix: The new camera matrix :math:`A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}` - - - :param map1: The first output map of type ``CV_32FC1`` or ``CV_16SC2`` - the second variant is more efficient - - - :param map2: The second output map of type ``CV_32FC1`` or ``CV_16UC1`` - the second variant is more efficient - - - -The function computes the joint undistortion+rectification transformation and represents the result in the form of maps for -:ref:`Remap` -. The undistorted image will look like the original, as if it was captured with a camera with camera matrix -``=newCameraMatrix`` -and zero distortion. In the case of monocular camera -``newCameraMatrix`` -is usually equal to -``cameraMatrix`` -, or it can be computed by -:ref:`GetOptimalNewCameraMatrix` -for a better control over scaling. In the case of stereo camera -``newCameraMatrix`` -is normally set to -``P1`` -or -``P2`` -computed by -:ref:`StereoRectify` -. - -Also, this new camera will be oriented differently in the coordinate space, according to -``R`` -. That, for example, helps to align two heads of a stereo camera so that the epipolar lines on both images become horizontal and have the same y- coordinate (in the case of horizontally aligned stereo camera). - -The function actually builds the maps for the inverse mapping algorithm that is used by -:ref:`Remap` -. That is, for each pixel -:math:`(u, v)` -in the destination (corrected and rectified) image the function computes the corresponding coordinates in the source image (i.e. in the original image from camera). The process is the following: - - - -.. math:: - - \begin{array}{l} x \leftarrow (u - {c'}_x)/{f'}_x \\ y \leftarrow (v - {c'}_y)/{f'}_y \\{[X\,Y\,W]} ^T \leftarrow R^{-1}*[x \, y \, 1]^T \\ x' \leftarrow X/W \\ y' \leftarrow Y/W \\ x" \leftarrow x' (1 + k_1 r^2 + k_2 r^4 + k_3 r^6) + 2p_1 x' y' + p_2(r^2 + 2 x'^2) \\ y" \leftarrow y' (1 + k_1 r^2 + k_2 r^4 + k_3 r^6) + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' \\ map_x(u,v) \leftarrow x" f_x + c_x \\ map_y(u,v) \leftarrow y" f_y + c_y \end{array} - - -where -:math:`(k_1, k_2, p_1, p_2[, k_3])` -are the distortion coefficients. - -In the case of a stereo camera this function is called twice, once for each camera head, after -:ref:`StereoRectify` -, which in its turn is called after -:ref:`StereoCalibrate` -. But if the stereo camera was not calibrated, it is still possible to compute the rectification transformations directly from the fundamental matrix using -:ref:`StereoRectifyUncalibrated` -. For each camera the function computes homography -``H`` -as the rectification transformation in pixel domain, not a rotation matrix -``R`` -in 3D space. The -``R`` -can be computed from -``H`` -as - - - -.. math:: - - \texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix} - - -where the -``cameraMatrix`` -can be chosen arbitrarily. - - -.. index:: POSIT - -.. _POSIT: - -POSIT ------ - - - - - - -.. cfunction:: void cvPOSIT( CvPOSITObject* posit_object, CvPoint2D32f* imagePoints, double focal_length, CvTermCriteria criteria, CvMatr32f rotationMatrix, CvVect32f translation_vector ) - - Implements the POSIT algorithm. - - - - - - - :param posit_object: Pointer to the object structure - - - :param imagePoints: Pointer to the object points projections on the 2D image plane - - - :param focal_length: Focal length of the camera used - - - :param criteria: Termination criteria of the iterative POSIT algorithm - - - :param rotationMatrix: Matrix of rotations - - - :param translation_vector: Translation vector - - - -The function implements the POSIT algorithm. Image coordinates are given in a camera-related coordinate system. The focal length may be retrieved using the camera calibration functions. At every iteration of the algorithm a new perspective projection of the estimated pose is computed. - -Difference norm between two projections is the maximal distance between corresponding points. The parameter -``criteria.epsilon`` -serves to stop the algorithm if the difference is small. - -An example of using ``cvPOSIT`` and ``cvCreatePOSITObject`` is available at http://opencv.willowgarage.com/wiki/Posit - - -.. index:: ProjectPoints2 - -.. _ProjectPoints2: - -ProjectPoints2 --------------- - - - - - - -.. cfunction:: void cvProjectPoints2( const CvMat* objectPoints, const CvMat* rvec, const CvMat* tvec, const CvMat* cameraMatrix, const CvMat* distCoeffs, CvMat* imagePoints, CvMat* dpdrot=NULL, CvMat* dpdt=NULL, CvMat* dpdf=NULL, CvMat* dpdc=NULL, CvMat* dpddist=NULL ) - - Project 3D points on to an image plane. - - - - - - - :param objectPoints: The array of object points, 3xN or Nx3 1-channel or 1xN or Nx1 3-channel , where N is the number of points in the view - - - :param rvec: The rotation vector, see :ref:`Rodrigues2` - - - :param tvec: The translation vector - - - :param cameraMatrix: The camera matrix :math:`A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - - :param imagePoints: The output array of image points, 2xN or Nx2 1-channel or 1xN or Nx1 2-channel - - - :param dpdrot: Optional 2Nx3 matrix of derivatives of image points with respect to components of the rotation vector - - - :param dpdt: Optional 2Nx3 matrix of derivatives of image points with respect to components of the translation vector - - - :param dpdf: Optional 2Nx2 matrix of derivatives of image points with respect to :math:`f_x` and :math:`f_y` - - - :param dpdc: Optional 2Nx2 matrix of derivatives of image points with respect to :math:`c_x` and :math:`c_y` - - - :param dpddist: Optional 2Nx4 matrix of derivatives of image points with respect to distortion coefficients - - - -The function computes projections of 3D -points to the image plane given intrinsic and extrinsic camera -parameters. Optionally, the function computes jacobians - matrices -of partial derivatives of image points coordinates (as functions of all the -input parameters) with respect to the particular parameters, intrinsic and/or -extrinsic. The jacobians are used during the global optimization -in -:ref:`CalibrateCamera2` -, -:ref:`FindExtrinsicCameraParams2` -and -:ref:`StereoCalibrate` -. The -function itself can also used to compute re-projection error given the -current intrinsic and extrinsic parameters. - -Note, that by setting -``rvec=tvec=(0,0,0)`` -, or by setting -``cameraMatrix`` -to 3x3 identity matrix, or by passing zero distortion coefficients, you can get various useful partial cases of the function, i.e. you can compute the distorted coordinates for a sparse set of points, or apply a perspective transformation (and also compute the derivatives) in the ideal zero-distortion setup etc. - - - -.. index:: ReprojectImageTo3D - -.. _ReprojectImageTo3D: - -ReprojectImageTo3D ------------------- - - - - - - -.. cfunction:: void cvReprojectImageTo3D( const CvArr* disparity, CvArr* _3dImage, const CvMat* Q, int handleMissingValues=0) - - Reprojects disparity image to 3D space. - - - - - - - :param disparity: The input single-channel 16-bit signed or 32-bit floating-point disparity image - - - :param _3dImage: The output 3-channel floating-point image of the same size as ``disparity`` . - Each element of ``_3dImage(x,y)`` will contain the 3D coordinates of the point ``(x,y)`` , computed from the disparity map. - - - :param Q: The :math:`4 \times 4` perspective transformation matrix that can be obtained with :ref:`StereoRectify` - - - :param handleMissingValues: If true, when the pixels with the minimal disparity (that corresponds to the outliers; see :ref:`FindStereoCorrespondenceBM` ) will be transformed to 3D points with some very large Z value (currently set to 10000) - - - -The function transforms 1-channel disparity map to 3-channel image representing a 3D surface. That is, for each pixel -``(x,y)`` -and the corresponding disparity -``d=disparity(x,y)`` -it computes: - - - -.. math:: - - \begin{array}{l} [X \; Y \; Z \; W]^T = \texttt{Q} *[x \; y \; \texttt{disparity} (x,y) \; 1]^T \\ \texttt{\_3dImage} (x,y) = (X/W, \; Y/W, \; Z/W) \end{array} - - -The matrix -``Q`` -can be arbitrary -:math:`4 \times 4` -matrix, e.g. the one computed by -:ref:`StereoRectify` -. To reproject a sparse set of points {(x,y,d),...} to 3D space, use -:ref:`PerspectiveTransform` -. - - -.. index:: RQDecomp3x3 - -.. _RQDecomp3x3: - -RQDecomp3x3 ------------ - - - - - - -.. cfunction:: void cvRQDecomp3x3( const CvMat *M, CvMat *R, CvMat *Q, CvMat *Qx=NULL, CvMat *Qy=NULL, CvMat *Qz=NULL, CvPoint3D64f *eulerAngles=NULL) - - Computes the 'RQ' decomposition of 3x3 matrices. - - - - - - - :param M: The 3x3 input matrix - - - :param R: The output 3x3 upper-triangular matrix - - - :param Q: The output 3x3 orthogonal matrix - - - :param Qx: Optional 3x3 rotation matrix around x-axis - - - :param Qy: Optional 3x3 rotation matrix around y-axis - - - :param Qz: Optional 3x3 rotation matrix around z-axis - - - :param eulerAngles: Optional three Euler angles of rotation - - - -The function computes a RQ decomposition using the given rotations. This function is used in -:ref:`DecomposeProjectionMatrix` -to decompose the left 3x3 submatrix of a projection matrix into a camera and a rotation matrix. - -It optionally returns three rotation matrices, one for each axis, and the three Euler angles -that could be used in OpenGL. - - -.. index:: ReleasePOSITObject - -.. _ReleasePOSITObject: - -ReleasePOSITObject ------------------- - - - - - - -.. cfunction:: void cvReleasePOSITObject( CvPOSITObject** posit_object ) - - Deallocates a 3D object structure. - - - - - - - :param posit_object: Double pointer to ``CvPOSIT`` structure - - - -The function releases memory previously allocated by the function -:ref:`CreatePOSITObject` -. - - -.. index:: ReleaseStereoBMState - -.. _ReleaseStereoBMState: - -ReleaseStereoBMState --------------------- - - - - - - -.. cfunction:: void cvReleaseStereoBMState( CvStereoBMState** state ) - - Releases block matching stereo correspondence structure. - - - - - - - :param state: Double pointer to the released structure. - - - -The function releases the stereo correspondence structure and all the associated internal buffers. - - -.. index:: ReleaseStereoGCState - -.. _ReleaseStereoGCState: - -ReleaseStereoGCState --------------------- - - - - - - -.. cfunction:: void cvReleaseStereoGCState( CvStereoGCState** state ) - - Releases the state structure of the graph cut-based stereo correspondence algorithm. - - - - - - - :param state: Double pointer to the released structure. - - - -The function releases the stereo correspondence structure and all the associated internal buffers. - - -.. index:: Rodrigues2 - -.. _Rodrigues2: - -Rodrigues2 ----------- - - - - - - -.. cfunction:: int cvRodrigues2( const CvMat* src, CvMat* dst, CvMat* jacobian=0 ) - - Converts a rotation matrix to a rotation vector or vice versa. - - - - - - - :param src: The input rotation vector (3x1 or 1x3) or rotation matrix (3x3) - - - :param dst: The output rotation matrix (3x3) or rotation vector (3x1 or 1x3), respectively - - - :param jacobian: Optional output Jacobian matrix, 3x9 or 9x3 - partial derivatives of the output array components with respect to the input array components - - - - - -.. math:: - - \begin{array}{l} \theta \leftarrow norm(r) \\ r \leftarrow r/ \theta \\ R = \cos{\theta} I + (1- \cos{\theta} ) r r^T + \sin{\theta} \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} \end{array} - - -Inverse transformation can also be done easily, since - - - -.. math:: - - \sin ( \theta ) \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} = \frac{R - R^T}{2} - - -A rotation vector is a convenient and most-compact representation of a rotation matrix -(since any rotation matrix has just 3 degrees of freedom). The representation is -used in the global 3D geometry optimization procedures like -:ref:`CalibrateCamera2` -, -:ref:`StereoCalibrate` -or -:ref:`FindExtrinsicCameraParams2` -. - - - -.. index:: StereoCalibrate - -.. _StereoCalibrate: - -StereoCalibrate ---------------- - - - - - - -.. cfunction:: double cvStereoCalibrate( const CvMat* objectPoints, const CvMat* imagePoints1, const CvMat* imagePoints2, const CvMat* pointCounts, CvMat* cameraMatrix1, CvMat* distCoeffs1, CvMat* cameraMatrix2, CvMat* distCoeffs2, CvSize imageSize, CvMat* R, CvMat* T, CvMat* E=0, CvMat* F=0, CvTermCriteria term_crit=cvTermCriteria( CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,1e-6), int flags=CV_CALIB_FIX_INTRINSIC ) - - Calibrates stereo camera. - - - - - - - :param objectPoints: The joint matrix of object points - calibration pattern features in the model coordinate space. It is floating-point 3xN or Nx3 1-channel, or 1xN or Nx1 3-channel array, where N is the total number of points in all views. - - - :param imagePoints1: The joint matrix of object points projections in the first camera views. It is floating-point 2xN or Nx2 1-channel, or 1xN or Nx1 2-channel array, where N is the total number of points in all views - - - :param imagePoints2: The joint matrix of object points projections in the second camera views. It is floating-point 2xN or Nx2 1-channel, or 1xN or Nx1 2-channel array, where N is the total number of points in all views - - - :param pointCounts: Integer 1xM or Mx1 vector (where M is the number of calibration pattern views) containing the number of points in each particular view. The sum of vector elements must match the size of ``objectPoints`` and ``imagePoints*`` (=N). - - - :param cameraMatrix1: The input/output first camera matrix: :math:`\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}` , :math:`j = 0,\, 1` . If any of ``CV_CALIB_USE_INTRINSIC_GUESS`` , ``CV_CALIB_FIX_ASPECT_RATIO`` , ``CV_CALIB_FIX_INTRINSIC`` or ``CV_CALIB_FIX_FOCAL_LENGTH`` are specified, some or all of the matrices' components must be initialized; see the flags description - - - :param distCoeffs1: The input/output vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. - - - :param cameraMatrix2: The input/output second camera matrix, as cameraMatrix1. - - - :param distCoeffs2: The input/output lens distortion coefficients for the second camera, as ``distCoeffs1`` . - - - :param imageSize: Size of the image, used only to initialize intrinsic camera matrix. - - - :param R: The output rotation matrix between the 1st and the 2nd cameras' coordinate systems. - - - :param T: The output translation vector between the cameras' coordinate systems. - - - :param E: The optional output essential matrix. - - - :param F: The optional output fundamental matrix. - - - :param term_crit: The termination criteria for the iterative optimization algorithm. - - - :param flags: Different flags, may be 0 or combination of the following values: - - * **CV_CALIB_FIX_INTRINSIC** If it is set, ``cameraMatrix?`` , as well as ``distCoeffs?`` are fixed, so that only ``R, T, E`` and ``F`` are estimated. - - * **CV_CALIB_USE_INTRINSIC_GUESS** The flag allows the function to optimize some or all of the intrinsic parameters, depending on the other flags, but the initial values are provided by the user. - - * **CV_CALIB_FIX_PRINCIPAL_POINT** The principal points are fixed during the optimization. - - * **CV_CALIB_FIX_FOCAL_LENGTH** :math:`f^{(j)}_x` and :math:`f^{(j)}_y` are fixed. - - * **CV_CALIB_FIX_ASPECT_RATIO** :math:`f^{(j)}_y` is optimized, but the ratio :math:`f^{(j)}_x/f^{(j)}_y` is fixed. - - * **CV_CALIB_SAME_FOCAL_LENGTH** Enforces :math:`f^{(0)}_x=f^{(1)}_x` and :math:`f^{(0)}_y=f^{(1)}_y` - - * **CV_CALIB_ZERO_TANGENT_DIST** Tangential distortion coefficients for each camera are set to zeros and fixed there. - - * **CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6** Do not change the corresponding radial distortion coefficient during the optimization. If ``CV_CALIB_USE_INTRINSIC_GUESS`` is set, the coefficient from the supplied ``distCoeffs`` matrix is used, otherwise it is set to 0. - - * **CV_CALIB_RATIONAL_MODEL** Enable coefficients k4, k5 and k6. To provide the backward compatibility, this extra flag should be explicitly specified to make the calibration function use the rational model and return 8 coefficients. If the flag is not set, the function will compute only 5 distortion coefficients. - - - - - -The function estimates transformation between the 2 cameras making a stereo pair. If we have a stereo camera, where the relative position and orientation of the 2 cameras is fixed, and if we computed poses of an object relative to the fist camera and to the second camera, (R1, T1) and (R2, T2), respectively (that can be done with -:ref:`FindExtrinsicCameraParams2` -), obviously, those poses will relate to each other, i.e. given ( -:math:`R_1` -, -:math:`T_1` -) it should be possible to compute ( -:math:`R_2` -, -:math:`T_2` -) - we only need to know the position and orientation of the 2nd camera relative to the 1st camera. That's what the described function does. It computes ( -:math:`R` -, -:math:`T` -) such that: - - - -.. math:: - - R_2=R*R_1 - T_2=R*T_1 + T, - - -Optionally, it computes the essential matrix E: - - - -.. math:: - - E= \vecthreethree{0}{-T_2}{T_1}{T_2}{0}{-T_0}{-T_1}{T_0}{0} *R - - -where -:math:`T_i` -are components of the translation vector -:math:`T` -: -:math:`T=[T_0, T_1, T_2]^T` -. And also the function can compute the fundamental matrix F: - - - -.. math:: - - F = cameraMatrix2^{-T} E cameraMatrix1^{-1} - - -Besides the stereo-related information, the function can also perform full calibration of each of the 2 cameras. However, because of the high dimensionality of the parameter space and noise in the input data the function can diverge from the correct solution. Thus, if intrinsic parameters can be estimated with high accuracy for each of the cameras individually (e.g. using -:ref:`CalibrateCamera2` -), it is recommended to do so and then pass -``CV_CALIB_FIX_INTRINSIC`` -flag to the function along with the computed intrinsic parameters. Otherwise, if all the parameters are estimated at once, it makes sense to restrict some parameters, e.g. pass -``CV_CALIB_SAME_FOCAL_LENGTH`` -and -``CV_CALIB_ZERO_TANGENT_DIST`` -flags, which are usually reasonable assumptions. - -Similarly to -:ref:`CalibrateCamera2` -, the function minimizes the total re-projection error for all the points in all the available views from both cameras. -The function returns the final value of the re-projection error. - -.. index:: StereoRectify - -.. _StereoRectify: - -StereoRectify -------------- - - - - - - -.. cfunction:: void cvStereoRectify( const CvMat* cameraMatrix1, const CvMat* cameraMatrix2, const CvMat* distCoeffs1, const CvMat* distCoeffs2, CvSize imageSize, const CvMat* R, const CvMat* T, CvMat* R1, CvMat* R2, CvMat* P1, CvMat* P2, CvMat* Q=0, int flags=CV_CALIB_ZERO_DISPARITY, double alpha=-1, CvSize newImageSize=cvSize(0,0), CvRect* roi1=0, CvRect* roi2=0) - - Computes rectification transforms for each head of a calibrated stereo camera. - - - :param cameraMatrix1: The first camera matrix. - - :param cameraMatrix2: The second camera matrix. - - :param distCoeffs1: The first camera distortion parameters. - - :param distCoeffs2: The second camera distortion parameters. - - :param imageSize: Size of the image used for stereo calibration. - - :param R: The rotation matrix between the 1st and the 2nd cameras' coordinate systems. - - :param T: The translation vector between the cameras' coordinate systems. - - :param R1, R2: The output :math:`3 \times 3` rectification transforms (rotation matrices) for the first and the second cameras, respectively. - - - :param P1, P2: The output :math:`3 \times 4` projection matrices in the new (rectified) coordinate systems. - - - :param Q: The output :math:`4 \times 4` disparity-to-depth mapping matrix, see :cpp:func:`reprojectImageTo3D` . - - - :param flags: The operation flags; may be 0 or ``CV_CALIB_ZERO_DISPARITY`` . If the flag is set, the function makes the principal points of each camera have the same pixel coordinates in the rectified views. And if the flag is not set, the function may still shift the images in horizontal or vertical direction (depending on the orientation of epipolar lines) in order to maximize the useful image area. - - - :param alpha: The free scaling parameter. If it is -1 , the functions performs some default scaling. Otherwise the parameter should be between 0 and 1. ``alpha=0`` means that the rectified images will be zoomed and shifted so that only valid pixels are visible (i.e. there will be no black areas after rectification). ``alpha=1`` means that the rectified image will be decimated and shifted so that all the pixels from the original images from the cameras are retained in the rectified images, i.e. no source image pixels are lost. Obviously, any intermediate value yields some intermediate result between those two extreme cases. - - - :param newImageSize: The new image resolution after rectification. The same size should be passed to :ref:`InitUndistortRectifyMap` , see the ``stereo_calib.cpp`` sample in OpenCV samples directory. By default, i.e. when (0,0) is passed, it is set to the original ``imageSize`` . Setting it to larger value can help you to preserve details in the original image, especially when there is big radial distortion. - - - :param roi1, roi2: The optional output rectangles inside the rectified images where all the pixels are valid. If ``alpha=0`` , the ROIs will cover the whole images, otherwise they likely be smaller, see the picture below - - - -The function computes the rotation matrices for each camera that (virtually) make both camera image planes the same plane. Consequently, that makes all the epipolar lines parallel and thus simplifies the dense stereo correspondence problem. On input the function takes the matrices computed by -:cpp:func:`stereoCalibrate` -and on output it gives 2 rotation matrices and also 2 projection matrices in the new coordinates. The 2 cases are distinguished by the function are: - - - - - -#. - Horizontal stereo, when 1st and 2nd camera views are shifted relative to each other mainly along the x axis (with possible small vertical shift). Then in the rectified images the corresponding epipolar lines in left and right cameras will be horizontal and have the same y-coordinate. P1 and P2 will look as: - - - - .. math:: - - \texttt{P1} = \begin{bmatrix} f & 0 & cx_1 & 0 \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} - - - - - .. math:: - - \texttt{P2} = \begin{bmatrix} f & 0 & cx_2 & T_x*f \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} , - - - where - :math:`T_x` - is horizontal shift between the cameras and - :math:`cx_1=cx_2` - if - ``CV_CALIB_ZERO_DISPARITY`` - is set. - - -#. - Vertical stereo, when 1st and 2nd camera views are shifted relative to each other mainly in vertical direction (and probably a bit in the horizontal direction too). Then the epipolar lines in the rectified images will be vertical and have the same x coordinate. P2 and P2 will look as: - - - - .. math:: - - \texttt{P1} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_1 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} - - - - - .. math:: - - \texttt{P2} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_2 & T_y*f \\ 0 & 0 & 1 & 0 \end{bmatrix} , - - - where - :math:`T_y` - is vertical shift between the cameras and - :math:`cy_1=cy_2` - if - ``CALIB_ZERO_DISPARITY`` - is set. - - -As you can see, the first 3 columns of -``P1`` -and -``P2`` -will effectively be the new "rectified" camera matrices. -The matrices, together with -``R1`` -and -``R2`` -, can then be passed to -:ref:`InitUndistortRectifyMap` -to initialize the rectification map for each camera. - -Below is the screenshot from -``stereo_calib.cpp`` -sample. Some red horizontal lines, as you can see, pass through the corresponding image regions, i.e. the images are well rectified (which is what most stereo correspondence algorithms rely on). The green rectangles are -``roi1`` -and -``roi2`` -- indeed, their interior are all valid pixels. - - - -.. image:: ../pics/stereo_undistort.jpg - - - - -.. index:: StereoRectifyUncalibrated - -.. _StereoRectifyUncalibrated: - -StereoRectifyUncalibrated -------------------------- - - - - - - -.. cfunction:: void cvStereoRectifyUncalibrated( const CvMat* points1, const CvMat* points2, const CvMat* F, CvSize imageSize, CvMat* H1, CvMat* H2, double threshold=5 ) - - Computes rectification transform for uncalibrated stereo camera. - - - - - - - :param points1, points2: The 2 arrays of corresponding 2D points. The same formats as in :ref:`FindFundamentalMat` are supported - - - :param F: The input fundamental matrix. It can be computed from the same set of point pairs using :ref:`FindFundamentalMat` . - - - :param imageSize: Size of the image. - - - :param H1, H2: The output rectification homography matrices for the first and for the second images. - - - :param threshold: The optional threshold used to filter out the outliers. If the parameter is greater than zero, then all the point pairs that do not comply the epipolar geometry well enough (that is, the points for which :math:`|\texttt{points2[i]}^T*\texttt{F}*\texttt{points1[i]}|>\texttt{threshold}` ) are rejected prior to computing the homographies. - Otherwise all the points are considered inliers. - - - -The function computes the rectification transformations without knowing intrinsic parameters of the cameras and their relative position in space, hence the suffix "Uncalibrated". Another related difference from -:ref:`StereoRectify` -is that the function outputs not the rectification transformations in the object (3D) space, but the planar perspective transformations, encoded by the homography matrices -``H1`` -and -``H2`` -. The function implements the algorithm -Hartley99 -. - -Note that while the algorithm does not need to know the intrinsic parameters of the cameras, it heavily depends on the epipolar geometry. Therefore, if the camera lenses have significant distortion, it would better be corrected before computing the fundamental matrix and calling this function. For example, distortion coefficients can be estimated for each head of stereo camera separately by using -:ref:`CalibrateCamera2` -and then the images can be corrected using -:ref:`Undistort2` -, or just the point coordinates can be corrected with -:ref:`UndistortPoints` -. - - - -.. index:: Undistort2 - -.. _Undistort2: - -Undistort2 ----------- - - - - - - -.. cfunction:: void cvUndistort2( const CvArr* src, CvArr* dst, const CvMat* cameraMatrix, const CvMat* distCoeffs, const CvMat* newCameraMatrix=0 ) - - Transforms an image to compensate for lens distortion. - - - - - - - :param src: The input (distorted) image - - - :param dst: The output (corrected) image; will have the same size and the same type as ``src`` - - - :param cameraMatrix: The input camera matrix :math:`A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - - -The function transforms the image to compensate radial and tangential lens distortion. - -The function is simply a combination of -:ref:`InitUndistortRectifyMap` -(with unity -``R`` -) and -:ref:`Remap` -(with bilinear interpolation). See the former function for details of the transformation being performed. - -Those pixels in the destination image, for which there is no correspondent pixels in the source image, are filled with 0's (black color). - -The particular subset of the source image that will be visible in the corrected image can be regulated by -``newCameraMatrix`` -. You can use -:ref:`GetOptimalNewCameraMatrix` -to compute the appropriate -``newCameraMatrix`` -, depending on your requirements. - -The camera matrix and the distortion parameters can be determined using -:ref:`CalibrateCamera2` -. If the resolution of images is different from the used at the calibration stage, -:math:`f_x, f_y, c_x` -and -:math:`c_y` -need to be scaled accordingly, while the distortion coefficients remain the same. - - - -.. index:: UndistortPoints - -.. _UndistortPoints: - -UndistortPoints ---------------- - - - - - - -.. cfunction:: void cvUndistortPoints( const CvMat* src, CvMat* dst, const CvMat* cameraMatrix, const CvMat* distCoeffs, const CvMat* R=NULL, const CvMat* P=NULL) - - Computes the ideal point coordinates from the observed point coordinates. - - - - - - - :param src: The observed point coordinates, 1xN or Nx1 2-channel (CV _ 32FC2 or CV _ 64FC2). - - - :param dst: The output ideal point coordinates, after undistortion and reverse perspective transformation , same format as ``src`` . - - - :param cameraMatrix: The camera matrix :math:`\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - - :param R: The rectification transformation in object space (3x3 matrix). ``R1`` or ``R2`` , computed by :cpp:func:`StereoRectify` can be passed here. If the matrix is empty, the identity transformation is used - - - :param P: The new camera matrix (3x3) or the new projection matrix (3x4). ``P1`` or ``P2`` , computed by :cpp:func:`StereoRectify` can be passed here. If the matrix is empty, the identity new camera matrix is used - - - -The function is similar to -:ref:`Undistort2` -and -:ref:`InitUndistortRectifyMap` -, but it operates on a sparse set of points instead of a raster image. Also the function does some kind of reverse transformation to -:ref:`ProjectPoints2` -(in the case of 3D object it will not reconstruct its 3D coordinates, of course; but for a planar object it will, up to a translation vector, if the proper -``R`` -is specified). - - - - -:: - - - - // (u,v) is the input point, (u', v') is the output point - // camera_matrix=[fx 0 cx; 0 fy cy; 0 0 1] - // P=[fx' 0 cx' tx; 0 fy' cy' ty; 0 0 1 tz] - x" = (u - cx)/fx - y" = (v - cy)/fy - (x',y') = undistort(x",y",dist_coeffs) - [X,Y,W]T = R*[x' y' 1]T - x = X/W, y = Y/W - u' = x*fx' + cx' - v' = y*fy' + cy', - - -.. - -where undistort() is approximate iterative algorithm that estimates the normalized original point coordinates out of the normalized distorted point coordinates ("normalized" means that the coordinates do not depend on the camera matrix). - -The function can be used both for a stereo camera head or for monocular camera (when R is -NULL -). diff --git a/doc/opencv1/c/core.rst b/doc/opencv1/c/core.rst deleted file mode 100644 index f24488f19c..0000000000 --- a/doc/opencv1/c/core.rst +++ /dev/null @@ -1,14 +0,0 @@ -**************************** -core. The Core Functionality -**************************** - -.. toctree:: - :maxdepth: 2 - - core_basic_structures - core_operations_on_arrays - core_dynamic_structures - core_drawing_functions - core_xml_yaml_persistence - core_clustering - core_utility_and_system_functions_and_macros diff --git a/doc/opencv1/c/core_basic_structures.rst b/doc/opencv1/c/core_basic_structures.rst deleted file mode 100644 index ec330aaebb..0000000000 --- a/doc/opencv1/c/core_basic_structures.rst +++ /dev/null @@ -1,1360 +0,0 @@ -Basic Structures -================ - -.. index:: CvPoint - -CvPoint -------- - -.. ctype:: CvPoint - - -2D point with integer coordinates (usually zero-based). - -:: - - - - typedef struct CvPoint - { - int x; - int y; - } - CvPoint; - - -.. - - - - - - .. attribute:: x - - - - x-coordinate - - - - .. attribute:: y - - - - y-coordinate - - - - - - -:: - - - - /* Constructor */ - inline CvPoint cvPoint( int x, int y ); - - /* Conversion from CvPoint2D32f */ - inline CvPoint cvPointFrom32f( CvPoint2D32f point ); - - -.. - - -.. index:: CvPoint2D32f - -.. _CvPoint2D32f: - -CvPoint2D32f ------------- - - - -.. ctype:: CvPoint2D32f - - - -2D point with floating-point coordinates - - - - -:: - - - - typedef struct CvPoint2D32f - { - float x; - float y; - } - CvPoint2D32f; - - -.. - - - - - - .. attribute:: x - - - - x-coordinate - - - - .. attribute:: y - - - - y-coordinate - - - - - - -:: - - - - /* Constructor */ - inline CvPoint2D32f cvPoint2D32f( double x, double y ); - - /* Conversion from CvPoint */ - inline CvPoint2D32f cvPointTo32f( CvPoint point ); - - -.. - - -.. index:: CvPoint3D32f - -.. _CvPoint3D32f: - -CvPoint3D32f ------------- - - - -.. ctype:: CvPoint3D32f - - - -3D point with floating-point coordinates - - - - -:: - - - - typedef struct CvPoint3D32f - { - float x; - float y; - float z; - } - CvPoint3D32f; - - -.. - - - - - - .. attribute:: x - - - - x-coordinate - - - - .. attribute:: y - - - - y-coordinate - - - - .. attribute:: z - - - - z-coordinate - - - - - - -:: - - - - /* Constructor */ - inline CvPoint3D32f cvPoint3D32f( double x, double y, double z ); - - -.. - - -.. index:: CvPoint2D64f - -.. _CvPoint2D64f: - -CvPoint2D64f ------------- - - - -.. ctype:: CvPoint2D64f - - - -2D point with double precision floating-point coordinates - - - - -:: - - - - typedef struct CvPoint2D64f - { - double x; - double y; - } - CvPoint2D64f; - - -.. - - - - - - .. attribute:: x - - - - x-coordinate - - - - .. attribute:: y - - - - y-coordinate - - - - - - -:: - - - - /* Constructor */ - inline CvPoint2D64f cvPoint2D64f( double x, double y ); - - /* Conversion from CvPoint */ - inline CvPoint2D64f cvPointTo64f( CvPoint point ); - - -.. - - -.. index:: CvPoint3D64f - -.. _CvPoint3D64f: - -CvPoint3D64f ------------- - - - -.. ctype:: CvPoint3D64f - - - -3D point with double precision floating-point coordinates - - - - -:: - - - - typedef struct CvPoint3D64f - { - double x; - double y; - double z; - } - CvPoint3D64f; - - -.. - - - - - - .. attribute:: x - - - - x-coordinate - - - - .. attribute:: y - - - - y-coordinate - - - - .. attribute:: z - - - - z-coordinate - - - - - - -:: - - - - /* Constructor */ - inline CvPoint3D64f cvPoint3D64f( double x, double y, double z ); - - -.. - - -.. index:: CvSize - -.. _CvSize: - -CvSize ------- - - - -.. ctype:: CvSize - - - -Pixel-accurate size of a rectangle. - - - - -:: - - - - typedef struct CvSize - { - int width; - int height; - } - CvSize; - - -.. - - - - - - .. attribute:: width - - - - Width of the rectangle - - - - .. attribute:: height - - - - Height of the rectangle - - - - - - -:: - - - - /* Constructor */ - inline CvSize cvSize( int width, int height ); - - -.. - - -.. index:: CvSize2D32f - -.. _CvSize2D32f: - -CvSize2D32f ------------ - - - -.. ctype:: CvSize2D32f - - - -Sub-pixel accurate size of a rectangle. - - - - -:: - - - - typedef struct CvSize2D32f - { - float width; - float height; - } - CvSize2D32f; - - -.. - - - - - - .. attribute:: width - - - - Width of the rectangle - - - - .. attribute:: height - - - - Height of the rectangle - - - - - - -:: - - - - /* Constructor */ - inline CvSize2D32f cvSize2D32f( double width, double height ); - - -.. - - -.. index:: CvRect - -.. _CvRect: - -CvRect ------- - - - -.. ctype:: CvRect - - - -Offset (usually the top-left corner) and size of a rectangle. - - - - -:: - - - - typedef struct CvRect - { - int x; - int y; - int width; - int height; - } - CvRect; - - -.. - - - - - - .. attribute:: x - - - - x-coordinate of the top-left corner - - - - .. attribute:: y - - - - y-coordinate of the top-left corner (bottom-left for Windows bitmaps) - - - - .. attribute:: width - - - - Width of the rectangle - - - - .. attribute:: height - - - - Height of the rectangle - - - - - - -:: - - - - /* Constructor */ - inline CvRect cvRect( int x, int y, int width, int height ); - - -.. - - -.. index:: CvScalar - -.. _CvScalar: - -CvScalar --------- - - - -.. ctype:: CvScalar - - - -A container for 1-,2-,3- or 4-tuples of doubles. - - - - -:: - - - - typedef struct CvScalar - { - double val[4]; - } - CvScalar; - - -.. - - - - -:: - - - - /* Constructor: - initializes val[0] with val0, val[1] with val1, etc. - */ - inline CvScalar cvScalar( double val0, double val1=0, - double val2=0, double val3=0 ); - /* Constructor: - initializes all of val[0]...val[3] with val0123 - */ - inline CvScalar cvScalarAll( double val0123 ); - - /* Constructor: - initializes val[0] with val0, and all of val[1]...val[3] with zeros - */ - inline CvScalar cvRealScalar( double val0 ); - - -.. - - -.. index:: CvTermCriteria - -.. _CvTermCriteria: - -CvTermCriteria --------------- - - - -.. ctype:: CvTermCriteria - - - -Termination criteria for iterative algorithms. - - - - -:: - - - - #define CV_TERMCRIT_ITER 1 - #define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER - #define CV_TERMCRIT_EPS 2 - - typedef struct CvTermCriteria - { - int type; - int max_iter; - double epsilon; - } - CvTermCriteria; - - -.. - - - - - - .. attribute:: type - - - - A combination of CV _ TERMCRIT _ ITER and CV _ TERMCRIT _ EPS - - - - .. attribute:: max_iter - - - - Maximum number of iterations - - - - .. attribute:: epsilon - - - - Required accuracy - - - - - - -:: - - - - /* Constructor */ - inline CvTermCriteria cvTermCriteria( int type, int max_iter, double epsilon ); - - /* Check and transform a CvTermCriteria so that - type=CV_TERMCRIT_ITER+CV_TERMCRIT_EPS - and both max_iter and epsilon are valid */ - CvTermCriteria cvCheckTermCriteria( CvTermCriteria criteria, - double default_eps, - int default_max_iters ); - - -.. - - -.. index:: CvMat - -.. _CvMat: - -CvMat ------ - - - -.. ctype:: CvMat - - - -A multi-channel matrix. - - - - -:: - - - - typedef struct CvMat - { - int type; - int step; - - int* refcount; - - union - { - uchar* ptr; - short* s; - int* i; - float* fl; - double* db; - } data; - - #ifdef __cplusplus - union - { - int rows; - int height; - }; - - union - { - int cols; - int width; - }; - #else - int rows; - int cols; - #endif - - } CvMat; - - -.. - - - - - - .. attribute:: type - - - - A CvMat signature (CV _ MAT _ MAGIC _ VAL) containing the type of elements and flags - - - - .. attribute:: step - - - - Full row length in bytes - - - - .. attribute:: refcount - - - - Underlying data reference counter - - - - .. attribute:: data - - - - Pointers to the actual matrix data - - - - .. attribute:: rows - - - - Number of rows - - - - .. attribute:: cols - - - - Number of columns - - - -Matrices are stored row by row. All of the rows are aligned by 4 bytes. - -.. index:: CvMatND - -.. _CvMatND: - -CvMatND -------- - - - -.. ctype:: CvMatND - - - -Multi-dimensional dense multi-channel array. - - - - -:: - - - - typedef struct CvMatND - { - int type; - int dims; - - int* refcount; - - union - { - uchar* ptr; - short* s; - int* i; - float* fl; - double* db; - } data; - - struct - { - int size; - int step; - } - dim[CV_MAX_DIM]; - - } CvMatND; - - -.. - - - - - - .. attribute:: type - - - - A CvMatND signature (CV _ MATND _ MAGIC _ VAL), combining the type of elements and flags - - - - .. attribute:: dims - - - - The number of array dimensions - - - - .. attribute:: refcount - - - - Underlying data reference counter - - - - .. attribute:: data - - - - Pointers to the actual matrix data - - - - .. attribute:: dim - - - - For each dimension, the pair (number of elements, distance between elements in bytes) - - - - -.. index:: CvSparseMat - -.. _CvSparseMat: - -CvSparseMat ------------ - - - -.. ctype:: CvSparseMat - - - -Multi-dimensional sparse multi-channel array. - - - - -:: - - - - typedef struct CvSparseMat - { - int type; - int dims; - int* refcount; - struct CvSet* heap; - void** hashtable; - int hashsize; - int valoffset; - int idxoffset; - int size[CV_MAX_DIM]; - - } CvSparseMat; - - -.. - - - - - - .. attribute:: type - - - - A CvSparseMat signature (CV _ SPARSE _ MAT _ MAGIC _ VAL), combining the type of elements and flags. - - - - .. attribute:: dims - - - - Number of dimensions - - - - .. attribute:: refcount - - - - Underlying reference counter. Not used. - - - - .. attribute:: heap - - - - A pool of hash table nodes - - - - .. attribute:: hashtable - - - - The hash table. Each entry is a list of nodes. - - - - .. attribute:: hashsize - - - - Size of the hash table - - - - - .. attribute:: valoffset - - - - The value offset of the array nodes, in bytes - - - - .. attribute:: idxoffset - - - - The index offset of the array nodes, in bytes - - - - .. attribute:: size - - - - Array of dimension sizes - - - - -.. index:: IplImage - -.. _IplImage: - -IplImage --------- - - - -.. ctype:: IplImage - - - -IPL image header - - - - -:: - - - - typedef struct _IplImage - { - int nSize; - int ID; - int nChannels; - int alphaChannel; - int depth; - char colorModel[4]; - char channelSeq[4]; - int dataOrder; - int origin; - int align; - int width; - int height; - struct _IplROI *roi; - struct _IplImage *maskROI; - void *imageId; - struct _IplTileInfo *tileInfo; - int imageSize; - char *imageData; - int widthStep; - int BorderMode[4]; - int BorderConst[4]; - char *imageDataOrigin; - } - IplImage; - - -.. - - - - - - .. attribute:: nSize - - - - ``sizeof(IplImage)`` - - - - .. attribute:: ID - - - - Version, always equals 0 - - - - .. attribute:: nChannels - - - - Number of channels. Most OpenCV functions support 1-4 channels. - - - - .. attribute:: alphaChannel - - - - Ignored by OpenCV - - - - .. attribute:: depth - - - - Channel depth in bits + the optional sign bit ( ``IPL_DEPTH_SIGN`` ). The supported depths are: - - - .. attribute:: IPL_DEPTH_8U - - - - Unsigned 8-bit integer - - - .. attribute:: IPL_DEPTH_8S - - - - Signed 8-bit integer - - - .. attribute:: IPL_DEPTH_16U - - - - Unsigned 16-bit integer - - - .. attribute:: IPL_DEPTH_16S - - - - Signed 16-bit integer - - - .. attribute:: IPL_DEPTH_32S - - - - Signed 32-bit integer - - - .. attribute:: IPL_DEPTH_32F - - - - Single-precision floating point - - - .. attribute:: IPL_DEPTH_64F - - - - Double-precision floating point - - - - - - .. attribute:: colorModel - - - - Ignored by OpenCV. The OpenCV function :ref:`CvtColor` requires the source and destination color spaces as parameters. - - - - .. attribute:: channelSeq - - - - Ignored by OpenCV - - - - .. attribute:: dataOrder - - - - 0 = ``IPL_DATA_ORDER_PIXEL`` - interleaved color channels, 1 - separate color channels. :ref:`CreateImage` only creates images with interleaved channels. For example, the usual layout of a color image is: :math:`b_{00} g_{00} r_{00} b_{10} g_{10} r_{10} ...` - - - - .. attribute:: origin - - - - 0 - top-left origin, 1 - bottom-left origin (Windows bitmap style) - - - - .. attribute:: align - - - - Alignment of image rows (4 or 8). OpenCV ignores this and uses widthStep instead. - - - - .. attribute:: width - - - - Image width in pixels - - - - .. attribute:: height - - - - Image height in pixels - - - - .. attribute:: roi - - - - Region Of Interest (ROI). If not NULL, only this image region will be processed. - - - - .. attribute:: maskROI - - - - Must be NULL in OpenCV - - - - .. attribute:: imageId - - - - Must be NULL in OpenCV - - - - .. attribute:: tileInfo - - - - Must be NULL in OpenCV - - - - .. attribute:: imageSize - - - - Image data size in bytes. For interleaved data, this equals :math:`\texttt{image->height} \cdot \texttt{image->widthStep}` - - - - .. attribute:: imageData - - - - A pointer to the aligned image data - - - - .. attribute:: widthStep - - - - The size of an aligned image row, in bytes - - - - .. attribute:: BorderMode - - - - Border completion mode, ignored by OpenCV - - - - .. attribute:: BorderConst - - - - Border completion mode, ignored by OpenCV - - - - .. attribute:: imageDataOrigin - - - - A pointer to the origin of the image data (not necessarily aligned). This is used for image deallocation. - - - -The -:ref:`IplImage` -structure was inherited from the Intel Image Processing Library, in which the format is native. OpenCV only supports a subset of possible -:ref:`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. - -.. index:: CvArr - -.. _CvArr: - -CvArr ------ - - - -.. ctype:: CvArr - - - -Arbitrary array - - - - -:: - - - - typedef void CvArr; - - -.. - -The metatype -``CvArr`` -is used -*only* -as a function parameter to specify 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. diff --git a/doc/opencv1/c/core_clustering.rst b/doc/opencv1/c/core_clustering.rst deleted file mode 100644 index e04758495d..0000000000 --- a/doc/opencv1/c/core_clustering.rst +++ /dev/null @@ -1,312 +0,0 @@ -Clustering -========== - -.. highlight:: c - - - -.. index:: KMeans2 - -.. _KMeans2: - -KMeans2 -------- - - - - - - -.. cfunction:: int cvKMeans2(const CvArr* samples, int nclusters, CvArr* labels, CvTermCriteria termcrit, int attempts=1, CvRNG* rng=0, int flags=0, CvArr* centers=0, double* compactness=0) - - Splits set of vectors by a given number of clusters. - - - - - - - :param samples: Floating-point matrix of input samples, one row per sample - - - :param nclusters: Number of clusters to split the set by - - - :param labels: Output integer vector storing cluster indices for every sample - - - :param termcrit: Specifies maximum number of iterations and/or accuracy (distance the centers can move by between subsequent iterations) - - - :param attempts: How many times the algorithm is executed using different initial labelings. The algorithm returns labels that yield the best compactness (see the last function parameter) - - - :param rng: Optional external random number generator; can be used to fully control the function behaviour - - - :param flags: Can be 0 or ``CV_KMEANS_USE_INITIAL_LABELS`` . The latter - value means that during the first (and possibly the only) attempt, the - function uses the user-supplied labels as the initial approximation - instead of generating random labels. For the second and further attempts, - the function will use randomly generated labels in any case - - - :param centers: The optional output array of the cluster centers - - - :param compactness: The optional output parameter, which is computed as :math:`\sum_i ||\texttt{samples}_i - \texttt{centers}_{\texttt{labels}_i}||^2` - after every attempt; the best (minimum) value is chosen and the - corresponding labels are returned by the function. Basically, the - user can use only the core of the function, set the number of - attempts to 1, initialize labels each time using a custom algorithm - ( ``flags=CV_KMEANS_USE_INITIAL_LABELS`` ) and, based on the output compactness - or any other criteria, choose the best clustering. - - - -The function -``cvKMeans2`` -implements a k-means algorithm that finds the -centers of -``nclusters`` -clusters and groups the input samples -around the clusters. On output, -:math:`\texttt{labels}_i` -contains a cluster index for -samples stored in the i-th row of the -``samples`` -matrix. - - - - -:: - - - - #include "cxcore.h" - #include "highgui.h" - - void main( int argc, char** argv ) - { - #define MAX_CLUSTERS 5 - CvScalar color_tab[MAX_CLUSTERS]; - IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 ); - CvRNG rng = cvRNG(0xffffffff); - - color_tab[0] = CV_RGB(255,0,0); - color_tab[1] = CV_RGB(0,255,0); - color_tab[2] = CV_RGB(100,100,255); - color_tab[3] = CV_RGB(255,0,255); - color_tab[4] = CV_RGB(255,255,0); - - cvNamedWindow( "clusters", 1 ); - - for(;;) - { - int k, cluster_count = cvRandInt(&rng) - int i, sample_count = cvRandInt(&rng) - CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 ); - CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 ); - - /* generate random sample from multigaussian distribution */ - for( k = 0; k < cluster_count; k++ ) - { - CvPoint center; - CvMat point_chunk; - center.x = cvRandInt(&rng) - center.y = cvRandInt(&rng) - cvGetRows( points, - &point_chunk, - k*sample_count/cluster_count, - (k == (cluster_count - 1)) ? - sample_count : - (k+1)*sample_count/cluster_count ); - cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL, - cvScalar(center.x,center.y,0,0), - cvScalar(img->width/6, img->height/6,0,0) ); - } - - /* shuffle samples */ - for( i = 0; i < sample_count/2; i++ ) - { - CvPoint2D32f* pt1 = - (CvPoint2D32f*)points->data.fl + cvRandInt(&rng) - CvPoint2D32f* pt2 = - (CvPoint2D32f*)points->data.fl + cvRandInt(&rng) - CvPoint2D32f temp; - CV_SWAP( *pt1, *pt2, temp ); - } - - cvKMeans2( points, cluster_count, clusters, - cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 )); - - cvZero( img ); - - for( i = 0; i < sample_count; i++ ) - { - CvPoint2D32f pt = ((CvPoint2D32f*)points->data.fl)[i]; - int cluster_idx = clusters->data.i[i]; - cvCircle( img, - cvPointFrom32f(pt), - 2, - color_tab[cluster_idx], - CV_FILLED ); - } - - cvReleaseMat( &points ); - cvReleaseMat( &clusters ); - - cvShowImage( "clusters", img ); - - int key = cvWaitKey(0); - if( key == 27 ) - break; - } - } - - -.. - - -.. index:: SeqPartition - -.. _SeqPartition: - -SeqPartition ------------- - - - - - - -.. cfunction:: int cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels, CvCmpFunc is_equal, void* userdata ) - - Splits a sequence into equivalency classes. - - - - - - - :param seq: The sequence to partition - - - :param storage: The storage block to store the sequence of equivalency classes. If it is NULL, the function uses ``seq->storage`` for output labels - - - :param labels: Ouput parameter. Double pointer to the sequence of 0-based labels of input sequence elements - - - :param is_equal: The relation function that should return non-zero if the two particular sequence elements are from the same class, and zero otherwise. The partitioning algorithm uses transitive closure of the relation function as an equivalency criteria - - - :param userdata: Pointer that is transparently passed to the ``is_equal`` function - - - - - - -:: - - - - typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); - - -.. - -The function -``cvSeqPartition`` -implements a quadratic algorithm for -splitting a set into one or more equivalancy classes. The function -returns the number of equivalency classes. - - - - - -:: - - - - - #include "cxcore.h" - #include "highgui.h" - #include - - CvSeq* point_seq = 0; - IplImage* canvas = 0; - CvScalar* colors = 0; - int pos = 10; - - int is_equal( const void* _a, const void* _b, void* userdata ) - { - CvPoint a = *(const CvPoint*)_a; - CvPoint b = *(const CvPoint*)_b; - double threshold = *(double*)userdata; - return (double)((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)) <= - threshold; - } - - void on_track( int pos ) - { - CvSeq* labels = 0; - double threshold = pos*pos; - int i, class_count = cvSeqPartition( point_seq, - 0, - &labels, - is_equal, - &threshold ); - printf(" - cvZero( canvas ); - - for( i = 0; i < labels->total; i++ ) - { - CvPoint pt = *(CvPoint*)cvGetSeqElem( point_seq, i ); - CvScalar color = colors[*(int*)cvGetSeqElem( labels, i )]; - cvCircle( canvas, pt, 1, color, -1 ); - } - - cvShowImage( "points", canvas ); - } - - int main( int argc, char** argv ) - { - CvMemStorage* storage = cvCreateMemStorage(0); - point_seq = cvCreateSeq( CV_32SC2, - sizeof(CvSeq), - sizeof(CvPoint), - storage ); - CvRNG rng = cvRNG(0xffffffff); - - int width = 500, height = 500; - int i, count = 1000; - canvas = cvCreateImage( cvSize(width,height), 8, 3 ); - - colors = (CvScalar*)cvAlloc( count*sizeof(colors[0]) ); - for( i = 0; i < count; i++ ) - { - CvPoint pt; - int icolor; - pt.x = cvRandInt( &rng ) - pt.y = cvRandInt( &rng ) - cvSeqPush( point_seq, &pt ); - icolor = cvRandInt( &rng ) | 0x00404040; - colors[i] = CV_RGB(icolor & 255, - (icolor >> 8)&255, - (icolor >> 16)&255); - } - - cvNamedWindow( "points", 1 ); - cvCreateTrackbar( "threshold", "points", &pos, 50, on_track ); - on_track(pos); - cvWaitKey(0); - return 0; - } - - -.. - diff --git a/doc/opencv1/c/core_drawing_functions.rst b/doc/opencv1/c/core_drawing_functions.rst deleted file mode 100644 index 5e6b19318e..0000000000 --- a/doc/opencv1/c/core_drawing_functions.rst +++ /dev/null @@ -1,898 +0,0 @@ -Drawing Functions -================= - -.. highlight:: c - - -Drawing functions work with matrices/images of arbitrary depth. -The boundaries of the shapes can be rendered with antialiasing (implemented only for 8-bit images for now). -All the functions include the parameter color that uses a rgb value (that may be constructed -with -``CV_RGB`` -macro or the :cpp:func:`cvScalar` function -) for color -images and brightness for grayscale images. For color images the order channel -is normally -*Blue, Green, Red* -, this is what -:cpp:func:`imshow` -, -:cpp:func:`imread` -and -:cpp:func:`imwrite` -expect -, so if you form a color using -:cpp:func:`cvScalar` -, it should look like: - - -.. math:: - - \texttt{cvScalar} (blue \_ component, green \_ component, red \_ component[, alpha \_ component]) - - -If you are using your own image rendering and I/O functions, you can use any channel ordering, the drawing functions process each channel independently and do not depend on the channel order or even on the color space used. The whole image can be converted from BGR to RGB or to a different color space using -:cpp:func:`cvtColor` -. - -If a drawn figure is partially or completely outside the image, the drawing functions clip it. Also, many drawing functions can handle pixel coordinates specified with sub-pixel accuracy, that is, the coordinates can be passed as fixed-point numbers, encoded as integers. The number of fractional bits is specified by the -``shift`` -parameter and the real point coordinates are calculated as -:math:`\texttt{Point}(x,y)\rightarrow\texttt{Point2f}(x*2^{-shift},y*2^{-shift})` -. This feature is especially effective wehn rendering antialiased shapes. - -Also, note that the functions do not support alpha-transparency - when the target image is 4-channnel, then the -``color[3]`` -is simply copied to the repainted pixels. Thus, if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image. - - -.. index:: Circle - -.. _Circle: - -Circle ------- - - - - - - -.. cfunction:: void cvCircle( CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int lineType=8, int shift=0 ) - - Draws a circle. - - - - - - - :param img: Image where the circle is drawn - - - :param center: Center of the circle - - - :param radius: Radius of the circle - - - :param color: Circle color - - - :param thickness: Thickness of the circle outline if positive, otherwise this indicates that a filled circle is to be drawn - - - :param lineType: Type of the circle boundary, see :ref:`Line` description - - - :param shift: Number of fractional bits in the center coordinates and radius value - - - -The function draws a simple or filled circle with a -given center and radius. - - -.. index:: ClipLine - -.. _ClipLine: - -ClipLine --------- - - - - - - -.. cfunction:: int cvClipLine( CvSize imgSize, CvPoint* pt1, CvPoint* pt2 ) - - Clips the line against the image rectangle. - - - - - - - :param imgSize: Size of the image - - - :param pt1: First ending point of the line segment. It is modified by the function. - - - :param pt2: Second ending point of the line segment. It is modified by the function. - - - -The function calculates a part of the line segment which is entirely within the image. -It returns 0 if the line segment is completely outside the image and 1 otherwise. - -.. index:: DrawContours - -.. _DrawContours: - -DrawContours ------------- - - - - - - -.. cfunction:: void cvDrawContours( CvArr *img, CvSeq* contour, CvScalar external_color, CvScalar hole_color, int max_level, int thickness=1, int lineType=8 ) - - Draws contour outlines or interiors in an image. - - - - - - - :param img: Image where the contours are to be drawn. As with any other drawing function, the contours are clipped with the ROI. - - - :param contour: Pointer to the first contour - - - :param external_color: Color of the external contours - - - :param hole_color: Color of internal contours (holes) - - - :param max_level: Maximal level for drawn contours. If 0, only ``contour`` is drawn. If 1, the contour and all contours following - it on the same level are drawn. If 2, all contours following and all - contours one level below the contours are drawn, and so forth. If the value - is negative, the function does not draw the contours following after ``contour`` but draws the child contours of ``contour`` up - to the :math:`|\texttt{max\_level}|-1` level. - - - :param thickness: Thickness of lines the contours are drawn with. - If it is negative (For example, =CV _ FILLED), the contour interiors are - drawn. - - - :param lineType: Type of the contour segments, see :ref:`Line` description - - - -The function draws contour outlines in the image if -:math:`\texttt{thickness} \ge 0` -or fills the area bounded by the contours if -:math:`\texttt{thickness}<0` -. - -Example: Connected component detection via contour functions - - - - -:: - - - - #include "cv.h" - #include "highgui.h" - - int main( int argc, char** argv ) - { - IplImage* src; - // the first command line parameter must be file name of binary - // (black-n-white) image - if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0) - { - IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 ); - CvMemStorage* storage = cvCreateMemStorage(0); - CvSeq* contour = 0; - - cvThreshold( src, src, 1, 255, CV_THRESH_BINARY ); - cvNamedWindow( "Source", 1 ); - cvShowImage( "Source", src ); - - cvFindContours( src, storage, &contour, sizeof(CvContour), - CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); - cvZero( dst ); - - for( ; contour != 0; contour = contour->h_next ) - { - CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 ); - /* replace CV_FILLED with 1 to see the outlines */ - cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 ); - } - - cvNamedWindow( "Components", 1 ); - cvShowImage( "Components", dst ); - cvWaitKey(0); - } - } - - -.. - - -.. index:: Ellipse - -.. _Ellipse: - -Ellipse -------- - - - - - - -.. cfunction:: void cvEllipse( CvArr* img, CvPoint center, CvSize axes, double angle, double start_angle, double end_angle, CvScalar color, int thickness=1, int lineType=8, int shift=0 ) - - Draws a simple or thick elliptic arc or an fills ellipse sector. - - - - - - - :param img: The image - - - :param center: Center of the ellipse - - - :param axes: Length of the ellipse axes - - - :param angle: Rotation angle - - - :param start_angle: Starting angle of the elliptic arc - - - :param end_angle: Ending angle of the elliptic arc. - - - :param color: Ellipse color - - - :param thickness: Thickness of the ellipse arc outline if positive, otherwise this indicates that a filled ellipse sector is to be drawn - - - :param lineType: Type of the ellipse boundary, see :ref:`Line` description - - - :param shift: Number of fractional bits in the center coordinates and axes' values - - - -The function draws a simple or thick elliptic -arc or fills an ellipse sector. The arc is clipped by the ROI rectangle. -A piecewise-linear approximation is used for antialiased arcs and -thick arcs. All the angles are given in degrees. The picture below -explains the meaning of the parameters. - -Parameters of Elliptic Arc - - - -.. image:: ../pics/ellipse.png - - - - -.. index:: EllipseBox - -.. _EllipseBox: - -EllipseBox ----------- - - - - - - -.. cfunction:: void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color, int thickness=1, int lineType=8, int shift=0 ) - - Draws a simple or thick elliptic arc or fills an ellipse sector. - - - - - - - :param img: Image - - - :param box: The enclosing box of the ellipse drawn - - - :param thickness: Thickness of the ellipse boundary - - - :param lineType: Type of the ellipse boundary, see :ref:`Line` description - - - :param shift: Number of fractional bits in the box vertex coordinates - - - -The function draws a simple or thick ellipse outline, or fills an ellipse. The functions provides a convenient way to draw an ellipse approximating some shape; that is what -:ref:`CamShift` -and -:ref:`FitEllipse` -do. The ellipse drawn is clipped by ROI rectangle. A piecewise-linear approximation is used for antialiased arcs and thick arcs. - - -.. index:: FillConvexPoly - -.. _FillConvexPoly: - -FillConvexPoly --------------- - - - - - - -.. cfunction:: void cvFillConvexPoly( CvArr* img, CvPoint* pts, int npts, CvScalar color, int lineType=8, int shift=0 ) - - Fills a convex polygon. - - - - - - - :param img: Image - - - :param pts: Array of pointers to a single polygon - - - :param npts: Polygon vertex counter - - - :param color: Polygon color - - - :param lineType: Type of the polygon boundaries, see :ref:`Line` description - - - :param shift: Number of fractional bits in the vertex coordinates - - - -The function fills a convex polygon's interior. -This function is much faster than the function -``cvFillPoly`` -and can fill not only convex polygons but any monotonic polygon, -i.e., a polygon whose contour intersects every horizontal line (scan -line) twice at the most. - - - -.. index:: FillPoly - -.. _FillPoly: - -FillPoly --------- - - - - - - -.. cfunction:: void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours, CvScalar color, int lineType=8, int shift=0 ) - - Fills a polygon's interior. - - - - - - - :param img: Image - - - :param pts: Array of pointers to polygons - - - :param npts: Array of polygon vertex counters - - - :param contours: Number of contours that bind the filled region - - - :param color: Polygon color - - - :param lineType: Type of the polygon boundaries, see :ref:`Line` description - - - :param shift: Number of fractional bits in the vertex coordinates - - - -The function fills an area bounded by several -polygonal contours. The function fills complex areas, for example, -areas with holes, contour self-intersection, and so forth. - - -.. index:: GetTextSize - -.. _GetTextSize: - -GetTextSize ------------ - - - - - - -.. cfunction:: void cvGetTextSize( const char* textString, const CvFont* font, CvSize* textSize, int* baseline ) - - Retrieves the width and height of a text string. - - - - - - - :param font: Pointer to the font structure - - - :param textString: Input string - - - :param textSize: Resultant size of the text string. Height of the text does not include the height of character parts that are below the baseline. - - - :param baseline: y-coordinate of the baseline relative to the bottom-most text point - - - -The function calculates the dimensions of a rectangle to enclose a text string when a specified font is used. - - -.. index:: InitFont - -.. _InitFont: - -InitFont --------- - - - - - - -.. cfunction:: void cvInitFont( CvFont* font, int fontFace, double hscale, double vscale, double shear=0, int thickness=1, int lineType=8 ) - - Initializes font structure. - - - - - - - :param font: Pointer to the font structure initialized by the function - - - :param fontFace: Font name identifier. Only a subset of Hershey fonts http://sources.isc.org/utils/misc/hershey-font.txt are supported now: - - - - * **CV_FONT_HERSHEY_SIMPLEX** normal size sans-serif font - - - * **CV_FONT_HERSHEY_PLAIN** small size sans-serif font - - - * **CV_FONT_HERSHEY_DUPLEX** normal size sans-serif font (more complex than ``CV_FONT_HERSHEY_SIMPLEX`` ) - - - * **CV_FONT_HERSHEY_COMPLEX** normal size serif font - - - * **CV_FONT_HERSHEY_TRIPLEX** normal size serif font (more complex than ``CV_FONT_HERSHEY_COMPLEX`` ) - - - * **CV_FONT_HERSHEY_COMPLEX_SMALL** smaller version of ``CV_FONT_HERSHEY_COMPLEX`` - - - * **CV_FONT_HERSHEY_SCRIPT_SIMPLEX** hand-writing style font - - - * **CV_FONT_HERSHEY_SCRIPT_COMPLEX** more complex variant of ``CV_FONT_HERSHEY_SCRIPT_SIMPLEX`` - - - - The parameter can be composited from one of the values above and an optional ``CV_FONT_ITALIC`` flag, which indicates italic or oblique font. - - - :param hscale: Horizontal scale. If equal to ``1.0f`` , the characters have the original width depending on the font type. If equal to ``0.5f`` , the characters are of half the original width. - - - :param vscale: Vertical scale. If equal to ``1.0f`` , the characters have the original height depending on the font type. If equal to ``0.5f`` , the characters are of half the original height. - - - :param shear: Approximate tangent of the character slope relative to the vertical line. A zero value means a non-italic font, ``1.0f`` means about a 45 degree slope, etc. - - - :param thickness: Thickness of the text strokes - - - :param lineType: Type of the strokes, see :ref:`Line` description - - - -The function initializes the font structure that can be passed to text rendering functions. - - - -.. index:: InitLineIterator - -.. _InitLineIterator: - -InitLineIterator ----------------- - - - - - - -.. cfunction:: int cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2, CvLineIterator* line_iterator, int connectivity=8, int left_to_right=0 ) - - Initializes the line iterator. - - - - - - - :param image: Image to sample the line from - - - :param pt1: First ending point of the line segment - - - :param pt2: Second ending point of the line segment - - - :param line_iterator: Pointer to the line iterator state structure - - - :param connectivity: The scanned line connectivity, 4 or 8. - - - :param left_to_right: - If ( :math:`\texttt{left\_to\_right} = 0` ) then the line is scanned in the specified order, from ``pt1`` to ``pt2`` . - If ( :math:`\texttt{left\_to\_right} \ne 0` ) the line is scanned from left-most point to right-most. - - - -The function initializes the line -iterator and returns the number of pixels between the two end points. -Both points must be inside the image. -After the iterator has been -initialized, all the points on the raster line that connects the -two ending points may be retrieved by successive calls of -``CV_NEXT_LINE_POINT`` -point. -The points on the line are -calculated one by one using a 4-connected or 8-connected Bresenham -algorithm. - -Example: Using line iterator to calculate the sum of pixel values along the color line. - - - - -:: - - - - - CvScalar sum_line_pixels( IplImage* image, CvPoint pt1, CvPoint pt2 ) - { - CvLineIterator iterator; - int blue_sum = 0, green_sum = 0, red_sum = 0; - int count = cvInitLineIterator( image, pt1, pt2, &iterator, 8, 0 ); - - for( int i = 0; i < count; i++ ){ - blue_sum += iterator.ptr[0]; - green_sum += iterator.ptr[1]; - red_sum += iterator.ptr[2]; - CV_NEXT_LINE_POINT(iterator); - - /* print the pixel coordinates: demonstrates how to calculate the - coordinates */ - { - int offset, x, y; - /* assume that ROI is not set, otherwise need to take it - into account. */ - offset = iterator.ptr - (uchar*)(image->imageData); - y = offset/image->widthStep; - x = (offset - y*image->widthStep)/(3*sizeof(uchar) - /* size of pixel */); - printf("( - } - } - return cvScalar( blue_sum, green_sum, red_sum ); - } - - - -.. - - -.. index:: Line - -.. _Line: - -Line ----- - - - - - - -.. cfunction:: void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int lineType=8, int shift=0 ) - - Draws a line segment connecting two points. - - - - - - - :param img: The image - - - :param pt1: First point of the line segment - - - :param pt2: Second point of the line segment - - - :param color: Line color - - - :param thickness: Line thickness - - - :param lineType: Type of the line: - - - - * **8** (or omitted) 8-connected line. - - - * **4** 4-connected line. - - - * **CV_AA** antialiased line. - - - - - - :param shift: Number of fractional bits in the point coordinates - - - -The function draws the line segment between -``pt1`` -and -``pt2`` -points in the image. The line is -clipped by the image or ROI rectangle. For non-antialiased lines -with integer coordinates the 8-connected or 4-connected Bresenham -algorithm is used. Thick lines are drawn with rounding endings. -Antialiased lines are drawn using Gaussian filtering. To specify -the line color, the user may use the macro -``CV_RGB( r, g, b )`` -. - - -.. index:: PolyLine - -.. _PolyLine: - -PolyLine --------- - - - - - - -.. cfunction:: void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed, CvScalar color, int thickness=1, int lineType=8, int shift=0 ) - - Draws simple or thick polygons. - - - - - - - :param pts: Array of pointers to polygons - - - :param npts: Array of polygon vertex counters - - - :param contours: Number of contours that bind the filled region - - - :param img: Image - - - :param is_closed: Indicates whether the polylines must be drawn - closed. If closed, the function draws the line from the last vertex - of every contour to the first vertex. - - - :param color: Polyline color - - - :param thickness: Thickness of the polyline edges - - - :param lineType: Type of the line segments, see :ref:`Line` description - - - :param shift: Number of fractional bits in the vertex coordinates - - - -The function draws single or multiple polygonal curves. - - -.. index:: PutText - -.. _PutText: - -PutText -------- - - - - - - -.. cfunction:: void cvPutText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color ) - - Draws a text string. - - - - - - - :param img: Input image - - - :param text: String to print - - - :param org: Coordinates of the bottom-left corner of the first letter - - - :param font: Pointer to the font structure - - - :param color: Text color - - - -The function renders the text in the image with -the specified font and color. The printed text is clipped by the ROI -rectangle. Symbols that do not belong to the specified font are -replaced with the symbol for a rectangle. - - -.. index:: Rectangle - -.. _Rectangle: - -Rectangle ---------- - - - - - - -.. cfunction:: void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int lineType=8, int shift=0 ) - - Draws a simple, thick, or filled rectangle. - - - - - - - :param img: Image - - - :param pt1: One of the rectangle's vertices - - - :param pt2: Opposite rectangle vertex - - - :param color: Line color (RGB) or brightness (grayscale image) - - - :param thickness: Thickness of lines that make up the rectangle. Negative values, e.g., CV _ FILLED, cause the function to draw a filled rectangle. - - - :param lineType: Type of the line, see :ref:`Line` description - - - :param shift: Number of fractional bits in the point coordinates - - - -The function draws a rectangle with two opposite corners -``pt1`` -and -``pt2`` -. - - -.. index:: CV_RGB - -.. _CV_RGB: - -CV_RGB ------- - - - - - - -.. cfunction:: \#define CV_RGB( r, g, b ) cvScalar( (b), (g), (r) ) - - Constructs a color value. - - - - - - - :param red: Red component - - - :param grn: Green component - - - :param blu: Blue component - - - diff --git a/doc/opencv1/c/core_dynamic_structures.rst b/doc/opencv1/c/core_dynamic_structures.rst deleted file mode 100644 index 3218f13e74..0000000000 --- a/doc/opencv1/c/core_dynamic_structures.rst +++ /dev/null @@ -1,3723 +0,0 @@ -Dynamic Structures -================== - -.. highlight:: c - - - -.. index:: CvMemStorage - -.. _CvMemStorage: - -CvMemStorage ------------- - - - -.. ctype:: CvMemStorage - - - -Growing memory storage. - - - - -:: - - - - typedef struct CvMemStorage - { - struct CvMemBlock* bottom;/* first allocated block */ - struct CvMemBlock* top; /* the current memory block - top of the stack */ - struct CvMemStorage* parent; /* borrows new blocks from */ - int block_size; /* block size */ - int free_space; /* free space in the ``top`` block (in bytes) */ - } CvMemStorage; - - -.. - -Memory storage is a low-level structure used to store dynamicly growing -data structures such as sequences, contours, graphs, subdivisions, etc. It -is organized as a list of memory blocks of equal size - -``bottom`` -field is the beginning of the list of blocks and -``top`` -is the -currently used block, but not necessarily the last block of the list. All -blocks between -``bottom`` -and -``top`` -, not including the -latter, are considered fully occupied; all blocks between -``top`` -and the last block, not including -``top`` -, are considered free -and -``top`` -itself is partly ocupied - -``free_space`` -contains the number of free bytes left in the end of -``top`` -. - -A new memory buffer that may be allocated explicitly by -:ref:`MemStorageAlloc` -function or implicitly by higher-level functions, -such as -:ref:`SeqPush` -, -:ref:`GraphAddEdge` -, etc., -``always`` -starts in the end of the current block if it fits there. After allocation, -``free_space`` -is decremented by the size of the allocated buffer -plus some padding to keep the proper alignment. When the allocated buffer -does not fit into the available portion of -``top`` -, the next storage -block from the list is taken as -``top`` -and -``free_space`` -is reset to the whole block size prior to the allocation. - -If there are no more free blocks, a new block is allocated (or borrowed -from the parent, see -:ref:`CreateChildMemStorage` -) and added to the end of -list. Thus, the storage behaves as a stack with -``bottom`` -indicating -bottom of the stack and the pair ( -``top`` -, -``free_space`` -) -indicating top of the stack. The stack top may be saved via -:ref:`SaveMemStoragePos` -, restored via -:ref:`RestoreMemStoragePos` -, -or reset via -:ref:`ClearStorage` -. - -.. index:: CvMemBlock - -.. _CvMemBlock: - -CvMemBlock ----------- - - - -.. ctype:: CvMemBlock - - - -Memory storage block. - - - - -:: - - - - typedef struct CvMemBlock - { - struct CvMemBlock* prev; - struct CvMemBlock* next; - } CvMemBlock; - - -.. - -The structure -:ref:`CvMemBlock` -represents a single block of memory -storage. The actual data in the memory blocks follows the header, that is, -the -:math:`i_{th}` -byte of the memory block can be retrieved with the expression -``((char*)(mem_block_ptr+1))[i]`` -. However, there is normally no need -to access the storage structure fields directly. - - -.. index:: CvMemStoragePos - -.. _CvMemStoragePos: - -CvMemStoragePos ---------------- - - - -.. ctype:: CvMemStoragePos - - - -Memory storage position. - - - - -:: - - - - typedef struct CvMemStoragePos - { - CvMemBlock* top; - int free_space; - } CvMemStoragePos; - - -.. - -The structure described above stores the position of the stack top that can be saved via -:ref:`SaveMemStoragePos` -and restored via -:ref:`RestoreMemStoragePos` -. - - -.. index:: CvSeq - -.. _CvSeq: - -CvSeq ------ - - - -.. ctype:: CvSeq - - - -Growable sequence of elements. - - - - -:: - - - - - #define CV_SEQUENCE_FIELDS() \ - int flags; /* micsellaneous flags */ \ - int header_size; /* size of sequence header */ \ - struct CvSeq* h_prev; /* previous sequence */ \ - struct CvSeq* h_next; /* next sequence */ \ - struct CvSeq* v_prev; /* 2nd previous sequence */ \ - struct CvSeq* v_next; /* 2nd next sequence */ \ - int total; /* total number of elements */ \ - int elem_size;/* size of sequence element in bytes */ \ - char* block_max;/* maximal bound of the last block */ \ - char* ptr; /* current write pointer */ \ - int delta_elems; /* how many elements allocated when the sequence grows - (sequence granularity) */ \ - CvMemStorage* storage; /* where the seq is stored */ \ - CvSeqBlock* free_blocks; /* free blocks list */ \ - CvSeqBlock* first; /* pointer to the first sequence block */ - - typedef struct CvSeq - { - CV_SEQUENCE_FIELDS() - } CvSeq; - - - -.. - -The structure -:ref:`CvSeq` -is a base for all of OpenCV dynamic data structures. - -Such an unusual definition via a helper macro simplifies the extension -of the structure -:ref:`CvSeq` -with additional parameters. To extend -:ref:`CvSeq` -the user may define a new structure and put user-defined -fields after all -:ref:`CvSeq` -fields that are included via the macro -``CV_SEQUENCE_FIELDS()`` -. - -There are two types of sequences - dense and sparse. The base type for dense -sequences is -:ref:`CvSeq` -and such sequences are used to represent -growable 1d arrays - vectors, stacks, queues, and deques. They have no gaps -in the middle - if an element is removed from the middle or inserted -into the middle of the sequence, the elements from the closer end are -shifted. Sparse sequences have -:ref:`CvSet` -as a base class and they are -discussed later in more detail. They are sequences of nodes; each may be either occupied or free as indicated by the node flag. Such -sequences are used for unordered data structures such as sets of elements, -graphs, hash tables and so forth. - -The field -``header_size`` -contains the actual size of the sequence -header and should be greater than or equal to -``sizeof(CvSeq)`` -. - -The fields -``h_prev`` -, -``h_next`` -, -``v_prev`` -, -``v_next`` -can be used to create hierarchical structures from separate sequences. The -fields -``h_prev`` -and -``h_next`` -point to the previous and -the next sequences on the same hierarchical level, while the fields -``v_prev`` -and -``v_next`` -point to the previous and the -next sequences in the vertical direction, that is, the parent and its first -child. But these are just names and the pointers can be used in a -different way. - -The field -``first`` -points to the first sequence block, whose structure is described below. - -The field -``total`` -contains the actual number of dense sequence elements and number of allocated nodes in a sparse sequence. - -The field -``flags`` -contains the particular dynamic type -signature ( -``CV_SEQ_MAGIC_VAL`` -for dense sequences and -``CV_SET_MAGIC_VAL`` -for sparse sequences) in the highest 16 -bits and miscellaneous information about the sequence. The lowest -``CV_SEQ_ELTYPE_BITS`` -bits contain the ID of the element -type. Most of sequence processing functions do not use element type but rather -element size stored in -``elem_size`` -. If a sequence contains the -numeric data for one of the -:ref:`CvMat` -type then the element type matches -to the corresponding -:ref:`CvMat` -element type, e.g., -``CV_32SC2`` -may be -used for a sequence of 2D points, -``CV_32FC1`` -for sequences of floating-point -values, etc. A -``CV_SEQ_ELTYPE(seq_header_ptr)`` -macro retrieves the -type of sequence elements. Processing functions that work with numerical -sequences check that -``elem_size`` -is equal to that calculated from -the type element size. Besides -:ref:`CvMat` -compatible types, there -are few extra element types defined in the -``cvtypes.h`` -header: - -Standard Types of Sequence Elements - - - - -:: - - - - - #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 /* unspecified type of - sequence elements */ - #define CV_SEQ_ELTYPE_PTR CV_USRTYPE1 /* =6 */ - #define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /* &elem: pointer to - element of other sequence */ - #define CV_SEQ_ELTYPE_INDEX CV_32SC1 /* #elem: index of element of - some other sequence */ - #define CV_SEQ_ELTYPE_GRAPH_EDGE CV_SEQ_ELTYPE_GENERIC /* &next_o, - &next_d, &vtx_o, &vtx_d */ - #define CV_SEQ_ELTYPE_GRAPH_VERTEX CV_SEQ_ELTYPE_GENERIC /* first_edge, - &(x,y) */ - #define CV_SEQ_ELTYPE_TRIAN_ATR CV_SEQ_ELTYPE_GENERIC /* vertex of the - binary tree */ - #define CV_SEQ_ELTYPE_CONNECTED_COMP CV_SEQ_ELTYPE_GENERIC /* connected - component */ - #define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /* (x,y,z) */ - - - -.. - -The next -``CV_SEQ_KIND_BITS`` -bits specify the kind of sequence: - -Standard Kinds of Sequences - - - - -:: - - - - - /* generic (unspecified) kind of sequence */ - #define CV_SEQ_KIND_GENERIC (0 << CV_SEQ_ELTYPE_BITS) - - /* dense sequence suntypes */ - #define CV_SEQ_KIND_CURVE (1 << CV_SEQ_ELTYPE_BITS) - #define CV_SEQ_KIND_BIN_TREE (2 << CV_SEQ_ELTYPE_BITS) - - /* sparse sequence (or set) subtypes */ - #define CV_SEQ_KIND_GRAPH (3 << CV_SEQ_ELTYPE_BITS) - #define CV_SEQ_KIND_SUBDIV2D (4 << CV_SEQ_ELTYPE_BITS) - - - -.. - -The remaining bits are used to identify different features specific -to certain sequence kinds and element types. For example, curves -made of points -``(CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_POINT)`` -, -together with the flag -``CV_SEQ_FLAG_CLOSED`` -, belong to the -type -``CV_SEQ_POLYGON`` -or, if other flags are used, to its -subtype. Many contour processing functions check the type of the input -sequence and report an error if they do not support this type. The -file -``cvtypes.h`` -stores the complete list of all supported -predefined sequence types and helper macros designed to get the sequence -type of other properties. The definition of the building -blocks of sequences can be found below. - - -.. index:: CvSeqBlock - -.. _CvSeqBlock: - -CvSeqBlock ----------- - - - -.. ctype:: CvSeqBlock - - - -Continuous sequence block. - - - - -:: - - - - - 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 */ - char* data; /* pointer to the first element of the block */ - } CvSeqBlock; - - - -.. - -Sequence blocks make up a circular double-linked list, so the pointers -``prev`` -and -``next`` -are never -``NULL`` -and point to the -previous and the next sequence blocks within the sequence. It means that -``next`` -of the last block is the first block and -``prev`` -of -the first block is the last block. The fields -``startIndex`` -and -``count`` -help to track the block location within the sequence. For -example, if the sequence consists of 10 elements and splits into three -blocks of 3, 5, and 2 elements, and the first block has the parameter -``startIndex = 2`` -, then pairs -``(startIndex, count)`` -for the sequence -blocks are -(2,3), (5, 5), and (10, 2) -correspondingly. The parameter -``startIndex`` -of the first block is usually -``0`` -unless -some elements have been inserted at the beginning of the sequence. - - -.. index:: CvSlice - -.. _CvSlice: - -CvSlice -------- - - - -.. ctype:: CvSlice - - - -A sequence slice. - - - - -:: - - - - typedef struct CvSlice - { - int start_index; - int end_index; - } CvSlice; - - inline CvSlice cvSlice( int start, int end ); - #define CV_WHOLE_SEQ_END_INDEX 0x3fffffff - #define CV_WHOLE_SEQ cvSlice(0, CV_WHOLE_SEQ_END_INDEX) - - /* calculates the sequence slice length */ - int cvSliceLength( CvSlice slice, const CvSeq* seq ); - - -.. - -Some of functions that operate on sequences take a -``CvSlice slice`` -parameter that is often set to the whole sequence (CV -_ -WHOLE -_ -SEQ) by -default. Either of the -``startIndex`` -and -``endIndex`` -may be negative or exceed the sequence length, -``startIndex`` -is -inclusive, and -``endIndex`` -is an exclusive boundary. If they are equal, -the slice is considered empty (i.e., contains no elements). Because -sequences are treated as circular structures, the slice may select a -few elements in the end of a sequence followed by a few elements at the -beginning of the sequence. For example, -``cvSlice(-2, 3)`` -in the case of -a 10-element sequence will select a 5-element slice, containing the pre-last -(8th), last (9th), the very first (0th), second (1th) and third (2nd) -elements. The functions normalize the slice argument in the following way: -first, -:ref:`SliceLength` -is called to determine the length of the slice, -then, -``startIndex`` -of the slice is normalized similarly to the -argument of -:ref:`GetSeqElem` -(i.e., negative indices are allowed). The -actual slice to process starts at the normalized -``startIndex`` -and lasts -:ref:`SliceLength` -elements (again, assuming the sequence is -a circular structure). - -If a function does not accept a slice argument, but you want to process -only a part of the sequence, the sub-sequence may be extracted -using the -:ref:`SeqSlice` -function, or stored into a continuous -buffer with -:ref:`CvtSeqToArray` -(optionally, followed by -:ref:`MakeSeqHeaderForArray` -). - - -.. index:: CvSet - -.. _CvSet: - -CvSet ------ - - - -.. ctype:: CvSet - - - -Collection of nodes. - - - - -:: - - - - typedef struct CvSetElem - { - int flags; /* it is negative if the node is free and zero or positive otherwise */ - struct CvSetElem* next_free; /* if the node is free, the field is a - pointer to next free node */ - } - CvSetElem; - - #define CV_SET_FIELDS() \ - CV_SEQUENCE_FIELDS() /* inherits from [#CvSeq CvSeq] */ \ - struct CvSetElem* free_elems; /* list of free nodes */ - - typedef struct CvSet - { - CV_SET_FIELDS() - } CvSet; - - -.. - -The structure -:ref:`CvSet` -is a base for OpenCV sparse data structures. - -As follows from the above declaration, -:ref:`CvSet` -inherits from -:ref:`CvSeq` -and it adds the -``free_elems`` -field, which -is a list of free nodes, to it. Every set node, whether free or not, is an -element of the underlying sequence. While there are no restrictions on -elements of dense sequences, the set (and derived structures) elements -must start with an integer field and be able to fit CvSetElem structure, -because these two fields (an integer followed by a pointer) are required -for the organization of a node set with the list of free nodes. If a node is -free, the -``flags`` -field is negative (the most-significant bit, or -MSB, of the field is set), and the -``next_free`` -points to the next -free node (the first free node is referenced by the -``free_elems`` -field of -:ref:`CvSet` -). And if a node is occupied, the -``flags`` -field -is positive and contains the node index that may be retrieved using the -( -``set_elem->flags & CV_SET_ELEM_IDX_MASK`` -) expressions, the rest of -the node content is determined by the user. In particular, the occupied -nodes are not linked as the free nodes are, so the second field can be -used for such a link as well as for some different purpose. The macro -``CV_IS_SET_ELEM(set_elem_ptr)`` -can be used to determined whether -the specified node is occupied or not. - -Initially the set and the list are empty. When a new node is requested -from the set, it is taken from the list of free nodes, which is then updated. If the list appears to be empty, a new sequence block is allocated -and all the nodes within the block are joined in the list of free -nodes. Thus, the -``total`` -field of the set is the total number of nodes -both occupied and free. When an occupied node is released, it is added -to the list of free nodes. The node released last will be occupied first. - -In OpenCV -:ref:`CvSet` -is used for representing graphs ( -:ref:`CvGraph` -), -sparse multi-dimensional arrays ( -:ref:`CvSparseMat` -), and planar subdivisions -:ref:`CvSubdiv2D` -. - - - -.. index:: CvGraph - -.. _CvGraph: - -CvGraph -------- - - - -.. ctype:: CvGraph - - - -Oriented or unoriented weighted graph. - - - - -:: - - - - #define CV_GRAPH_VERTEX_FIELDS() \ - int flags; /* vertex flags */ \ - struct CvGraphEdge* first; /* the first incident edge */ - - typedef struct CvGraphVtx - { - CV_GRAPH_VERTEX_FIELDS() - } - CvGraphVtx; - - #define CV_GRAPH_EDGE_FIELDS() \ - int flags; /* edge flags */ \ - float weight; /* edge weight */ \ - struct CvGraphEdge* next[2]; /* the next edges in the incidence lists for staring (0) */ \ - /* and ending (1) vertices */ \ - struct CvGraphVtx* vtx[2]; /* the starting (0) and ending (1) vertices */ - - typedef struct CvGraphEdge - { - CV_GRAPH_EDGE_FIELDS() - } - CvGraphEdge; - - #define CV_GRAPH_FIELDS() \ - CV_SET_FIELDS() /* set of vertices */ \ - CvSet* edges; /* set of edges */ - - typedef struct CvGraph - { - CV_GRAPH_FIELDS() - } - CvGraph; - - - -.. - -The structure -:ref:`CvGraph` -is a base for graphs used in OpenCV. - -The graph structure inherits from -:ref:`CvSet` -- which describes common graph properties and the graph vertices, and contains another set as a member - which describes the graph edges. - -The vertex, edge, and the graph header structures are declared using the -same technique as other extendible OpenCV structures - via macros, which -simplify extension and customization of the structures. While the vertex -and edge structures do not inherit from -:ref:`CvSetElem` -explicitly, they -satisfy both conditions of the set elements: having an integer field in -the beginning and fitting within the CvSetElem structure. The -``flags`` -fields are -used as for indicating occupied vertices and edges as well as for other -purposes, for example, for graph traversal (see -:ref:`CreateGraphScanner` -et al.), so it is better not to use them directly. - -The graph is represented as a set of edges each of which has a list of -incident edges. The incidence lists for different vertices are interleaved -to avoid information duplication as much as posssible. - -The graph may be oriented or unoriented. In the latter case there is no -distiction between the edge connecting vertex -:math:`A` -with vertex -:math:`B` -and the edge -connecting vertex -:math:`B` -with vertex -:math:`A` -- only one of them can exist in the -graph at the same moment and it represents both -:math:`A \rightarrow B` -and -:math:`B \rightarrow A` -edges. - - -.. index:: CvGraphScanner - -.. _CvGraphScanner: - -CvGraphScanner --------------- - - - -.. ctype:: CvGraphScanner - - - -Graph traversal state. - - - - -:: - - - - typedef struct CvGraphScanner - { - CvGraphVtx* vtx; /* current graph vertex (or current edge origin) */ - CvGraphVtx* dst; /* current graph edge destination vertex */ - CvGraphEdge* edge; /* current edge */ - - CvGraph* graph; /* the graph */ - CvSeq* stack; /* the graph vertex stack */ - int index; /* the lower bound of certainly visited vertices */ - int mask; /* event mask */ - } - CvGraphScanner; - - - -.. - -The structure -:ref:`CvGraphScanner` -is used for depth-first graph traversal. See discussion of the functions below. - -cvmacro -Helper macro for a tree node type declaration. - -The macro -``CV_TREE_NODE_FIELDS()`` -is used to declare structures -that can be organized into hierarchical strucutures (trees), such as -:ref:`CvSeq` -- the basic type for all dynamic structures. The trees -created with nodes declared using this macro can be processed using the -functions described below in this section. - - -.. index:: CvTreeNodeIterator - -.. _CvTreeNodeIterator: - -CvTreeNodeIterator ------------------- - - - -.. ctype:: CvTreeNodeIterator - - - -Opens existing or creates new file storage. - - - - -:: - - - - typedef struct CvTreeNodeIterator - { - const void* node; - int level; - int max_level; - } - CvTreeNodeIterator; - - -.. - - - - -:: - - - - #define CV_TREE_NODE_FIELDS(node_type) \ - int flags; /* micsellaneous 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 */ - - - -.. - -The structure -:ref:`CvTreeNodeIterator` -is used to traverse trees. Each tree node should start with the certain fields which are defined by -``CV_TREE_NODE_FIELDS(...)`` -macro. In C++ terms, each tree node should be a structure "derived" from - - - - -:: - - - - struct _BaseTreeNode - { - CV_TREE_NODE_FIELDS(_BaseTreeNode); - } - - -.. - -``CvSeq`` -, -``CvSet`` -, -``CvGraph`` -and other dynamic structures derived from -``CvSeq`` -comply with the requirement. - - -.. index:: ClearGraph - -.. _ClearGraph: - -ClearGraph ----------- - - - - - - -.. cfunction:: void cvClearGraph( CvGraph* graph ) - - Clears a graph. - - - - - - - :param graph: Graph - - - -The function removes all vertices and edges from a graph. The function has O(1) time complexity. - - -.. index:: ClearMemStorage - -.. _ClearMemStorage: - -ClearMemStorage ---------------- - - - - - - -.. cfunction:: void cvClearMemStorage( CvMemStorage* storage ) - - Clears memory storage. - - - - - - - :param storage: Memory storage - - - -The function resets the top (free space -boundary) of the storage to the very beginning. This function does not -deallocate any memory. If the storage has a parent, the function returns -all blocks to the parent. - - -.. index:: ClearSeq - -.. _ClearSeq: - -ClearSeq --------- - - - - - - -.. cfunction:: void cvClearSeq( CvSeq* seq ) - - Clears a sequence. - - - - - - - :param seq: Sequence - - - -The function removes all elements from a -sequence. The function does not return the memory to the storage block, but this -memory is reused later when new elements are added to the sequence. The function has -'O(1)' time complexity. - - - -.. index:: ClearSet - -.. _ClearSet: - -ClearSet --------- - - - - - - -.. cfunction:: void cvClearSet( CvSet* setHeader ) - - Clears a set. - - - - - - - :param setHeader: Cleared set - - - -The function removes all elements from set. It has O(1) time complexity. - - - -.. index:: CloneGraph - -.. _CloneGraph: - -CloneGraph ----------- - - - - - - -.. cfunction:: CvGraph* cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ) - - Clones a graph. - - - - - - - :param graph: The graph to copy - - - :param storage: Container for the copy - - - -The function creates a full copy of the specified graph. If the -graph vertices or edges have pointers to some external data, it can still be -shared between the copies. The vertex and edge indices in the new graph -may be different from the original because the function defragments -the vertex and edge sets. - - -.. index:: CloneSeq - -.. _CloneSeq: - -CloneSeq --------- - - - - - - -.. cfunction:: CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage=NULL ) - - Creates a copy of a sequence. - - - - - - - :param seq: Sequence - - - :param storage: The destination storage block to hold the new sequence header and the copied data, if any. If it is NULL, the function uses the storage block containing the input sequence. - - - -The function makes a complete copy of the input sequence and returns it. - -The call - - - -:: - - - - cvCloneSeq( seq, storage ) - - -.. - -is equivalent to - - - - -:: - - - - cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 ) - - -.. - - -.. index:: CreateChildMemStorage - -.. _CreateChildMemStorage: - -CreateChildMemStorage ---------------------- - - - - - - -.. cfunction:: CvMemStorage* cvCreateChildMemStorage(CvMemStorage* parent) - - Creates child memory storage. - - - - - - - :param parent: Parent memory storage - - - -The function creates a child memory -storage that is similar to simple memory storage except for the -differences in the memory allocation/deallocation mechanism. When a -child storage needs a new block to add to the block list, it tries -to get this block from the parent. The first unoccupied parent block -available is taken and excluded from the parent block list. If no blocks -are available, the parent either allocates a block or borrows one from -its own parent, if any. In other words, the chain, or a more complex -structure, of memory storages where every storage is a child/parent of -another is possible. When a child storage is released or even cleared, -it returns all blocks to the parent. In other aspects, child storage -is the same as simple storage. - -Child storage is useful in the following situation. Imagine -that the user needs to process dynamic data residing in a given storage area and -put the result back to that same storage area. With the simplest approach, -when temporary data is resided in the same storage area as the input and -output data, the storage area will look as follows after processing: - -Dynamic data processing without using child storage - - - -.. image:: ../pics/memstorage1.png - - - -That is, garbage appears in the middle of the storage. However, if -one creates a child memory storage at the beginning of processing, -writes temporary data there, and releases the child storage at the end, -no garbage will appear in the source/destination storage: - -Dynamic data processing using a child storage - - - -.. image:: ../pics/memstorage2.png - - - - -.. index:: CreateGraph - -.. _CreateGraph: - -CreateGraph ------------ - - - - - - -.. cfunction:: CvGraph* cvCreateGraph( int graph_flags, int header_size, int vtx_size, int edge_size, CvMemStorage* storage ) - - Creates an empty graph. - - - - - - - :param graph_flags: Type of the created graph. Usually, it is either ``CV_SEQ_KIND_GRAPH`` for generic unoriented graphs and ``CV_SEQ_KIND_GRAPH | CV_GRAPH_FLAG_ORIENTED`` for generic oriented graphs. - - - :param header_size: Graph header size; may not be less than ``sizeof(CvGraph)`` - - - :param vtx_size: Graph vertex size; the custom vertex structure must start with :ref:`CvGraphVtx` (use ``CV_GRAPH_VERTEX_FIELDS()`` ) - - - :param edge_size: Graph edge size; the custom edge structure must start with :ref:`CvGraphEdge` (use ``CV_GRAPH_EDGE_FIELDS()`` ) - - - :param storage: The graph container - - - -The function creates an empty graph and returns a pointer to it. - - -.. index:: CreateGraphScanner - -.. _CreateGraphScanner: - -CreateGraphScanner ------------------- - - - - - - -.. cfunction:: CvGraphScanner* cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx=NULL, int mask=CV_GRAPH_ALL_ITEMS ) - - Creates structure for depth-first graph traversal. - - - - - - - :param graph: Graph - - - :param vtx: Initial vertex to start from. If NULL, the traversal starts from the first vertex (a vertex with the minimal index in the sequence of vertices). - - - :param mask: Event mask indicating which events are of interest to the user (where :ref:`NextGraphItem` function returns control to the user) It can be ``CV_GRAPH_ALL_ITEMS`` (all events are of interest) or a combination of the following flags: - - - * **CV_GRAPH_VERTEX** stop at the graph vertices visited for the first time - - * **CV_GRAPH_TREE_EDGE** stop at tree edges ( ``tree edge`` is the edge connecting the last visited vertex and the vertex to be visited next) - - * **CV_GRAPH_BACK_EDGE** stop at back edges ( ``back edge`` is an edge connecting the last visited vertex with some of its ancestors in the search tree) - - * **CV_GRAPH_FORWARD_EDGE** stop at forward edges ( ``forward edge`` is an edge conecting the last visited vertex with some of its descendants in the search tree. The forward edges are only possible during oriented graph traversal) - - * **CV_GRAPH_CROSS_EDGE** stop at cross edges ( ``cross edge`` is an edge connecting different search trees or branches of the same tree. The ``cross edges`` are only possible during oriented graph traversal) - - * **CV_GRAPH_ANY_EDGE** stop at any edge ( ``tree, back, forward`` , and ``cross edges`` ) - - * **CV_GRAPH_NEW_TREE** stop in the beginning of every new search tree. When the traversal procedure visits all vertices and edges reachable from the initial vertex (the visited vertices together with tree edges make up a tree), it searches for some unvisited vertex in the graph and resumes the traversal process from that vertex. Before starting a new tree (including the very first tree when ``cvNextGraphItem`` is called for the first time) it generates a ``CV_GRAPH_NEW_TREE`` event. For unoriented graphs, each search tree corresponds to a connected component of the graph. - - * **CV_GRAPH_BACKTRACKING** stop at every already visited vertex during backtracking - returning to already visited vertexes of the traversal tree. - - - - - -The function creates a structure for depth-first graph traversal/search. The initialized structure is used in the -:ref:`NextGraphItem` -function - the incremental traversal procedure. - - -.. index:: CreateMemStorage - -.. _CreateMemStorage: - -CreateMemStorage ----------------- - - - - - - -.. cfunction:: CvMemStorage* cvCreateMemStorage( int blockSize=0 ) - - Creates memory storage. - - - - - - - :param blockSize: Size of the storage blocks in bytes. If it is 0, the block size is set to a default value - currently it is about 64K. - - - -The function creates an empty memory storage. See -:ref:`CvMemStorage` -description. - - -.. index:: CreateSeq - -.. _CreateSeq: - -CreateSeq ---------- - - - - - - -.. cfunction:: CvSeq* cvCreateSeq( int seqFlags, int headerSize, int elemSize, CvMemStorage* storage) - - Creates a sequence. - - - - - - - :param seqFlags: Flags of the created sequence. If the sequence is not passed to any function working with a specific type of sequences, the sequence value may be set to 0, otherwise the appropriate type must be selected from the list of predefined sequence types. - - - :param headerSize: Size of the sequence header; must be greater than or equal to ``sizeof(CvSeq)`` . If a specific type or its extension is indicated, this type must fit the base type header. - - - :param elemSize: Size of the sequence elements in bytes. The size must be consistent with the sequence type. For example, for a sequence of points to be created, the element type ``CV_SEQ_ELTYPE_POINT`` should be specified and the parameter ``elemSize`` must be equal to ``sizeof(CvPoint)`` . - - - :param storage: Sequence location - - - -The function creates a sequence and returns -the pointer to it. The function allocates the sequence header in -the storage block as one continuous chunk and sets the structure -fields -``flags`` -, -``elemSize`` -, -``headerSize`` -, and -``storage`` -to passed values, sets -``delta_elems`` -to the -default value (that may be reassigned using the -:ref:`SetSeqBlockSize` -function), and clears other header fields, including the space following -the first -``sizeof(CvSeq)`` -bytes. - - -.. index:: CreateSet - -.. _CreateSet: - -CreateSet ---------- - - - - - - -.. cfunction:: CvSet* cvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage* storage ) - - Creates an empty set. - - - - - - - :param set_flags: Type of the created set - - - :param header_size: Set header size; may not be less than ``sizeof(CvSet)`` - - - :param elem_size: Set element size; may not be less than :ref:`CvSetElem` - - - :param storage: Container for the set - - - -The function creates an empty set with a specified header size and element size, and returns the pointer to the set. This function is just a thin layer on top of -:ref:`CreateSeq` -. - - -.. index:: CvtSeqToArray - -.. _CvtSeqToArray: - -CvtSeqToArray -------------- - - - - - - -.. cfunction:: void* cvCvtSeqToArray( const CvSeq* seq, void* elements, CvSlice slice=CV_WHOLE_SEQ ) - - Copies a sequence to one continuous block of memory. - - - - - - - :param seq: Sequence - - - :param elements: Pointer to the destination array that must be large enough. It should be a pointer to data, not a matrix header. - - - :param slice: The sequence portion to copy to the array - - - -The function copies the entire sequence or subsequence to the specified buffer and returns the pointer to the buffer. - - -.. index:: EndWriteSeq - -.. _EndWriteSeq: - -EndWriteSeq ------------ - - - - - - -.. cfunction:: CvSeq* cvEndWriteSeq( CvSeqWriter* writer ) - - Finishes the process of writing a sequence. - - - - - - - :param writer: Writer state - - - -The function finishes the writing process and -returns the pointer to the written sequence. The function also truncates -the last incomplete sequence block to return the remaining part of the -block to memory storage. After that, the sequence can be read and -modified safely. See -:ref:`cvStartWriteSeq` -and -:ref:`cvStartAppendToSeq` - -.. index:: FindGraphEdge - -.. _FindGraphEdge: - -FindGraphEdge -------------- - - - - - - -.. cfunction:: CvGraphEdge* cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ) - - Finds an edge in a graph. - - - - - - -:: - - - - - #define cvGraphFindEdge cvFindGraphEdge - - - -.. - - - - - :param graph: Graph - - - :param start_idx: Index of the starting vertex of the edge - - - :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. - - - -The function finds the graph edge connecting two specified vertices and returns a pointer to it or NULL if the edge does not exist. - - -.. index:: FindGraphEdgeByPtr - -.. _FindGraphEdgeByPtr: - -FindGraphEdgeByPtr ------------------- - - - - - - -.. cfunction:: CvGraphEdge* cvFindGraphEdgeByPtr( const CvGraph* graph, const CvGraphVtx* startVtx, const CvGraphVtx* endVtx ) - - Finds an edge in a graph by using its pointer. - - - - - - -:: - - - - #define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr - - -.. - - - - - :param graph: Graph - - - :param startVtx: Pointer to the starting vertex of the edge - - - :param endVtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. - - - -The function finds the graph edge connecting two specified vertices and returns pointer to it or NULL if the edge does not exists. - - -.. index:: FlushSeqWriter - -.. _FlushSeqWriter: - -FlushSeqWriter --------------- - - - - - - -.. cfunction:: void cvFlushSeqWriter( CvSeqWriter* writer ) - - Updates sequence headers from the writer. - - - - - - - :param writer: Writer state - - - -The function is intended to enable the user to -read sequence elements, whenever required, during the writing process, -e.g., in order to check specific conditions. The function updates the -sequence headers to make reading from the sequence possible. The writer -is not closed, however, so that the writing process can be continued at -any time. If an algorithm requires frequent flushes, consider using -:ref:`SeqPush` -instead. - - -.. index:: GetGraphVtx - -.. _GetGraphVtx: - -GetGraphVtx ------------ - - - - - - -.. cfunction:: CvGraphVtx* cvGetGraphVtx( CvGraph* graph, int vtx_idx ) - - Finds a graph vertex by using its index. - - - - - - - :param graph: Graph - - - :param vtx_idx: Index of the vertex - - - -The function finds the graph vertex by using its index and returns the pointer to it or NULL if the vertex does not belong to the graph. - - - -.. index:: GetSeqElem - -.. _GetSeqElem: - -GetSeqElem ----------- - - - - - - -.. cfunction:: char* cvGetSeqElem( const CvSeq* seq, int index ) - - Returns a pointer to a sequence element according to its index. - - - - - - -:: - - - - #define CV_GET_SEQ_ELEM( TYPE, seq, index ) (TYPE*)cvGetSeqElem( (CvSeq*)(seq), (index) ) - - -.. - - - - - :param seq: Sequence - - - :param index: Index of element - - - -The function finds the element with the given -index in the sequence and returns the pointer to it. If the element -is not found, the function returns 0. The function supports negative -indices, where -1 stands for the last sequence element, -2 stands for -the one before last, etc. If the sequence is most likely to consist of -a single sequence block or the desired element is likely to be located -in the first block, then the macro -``CV_GET_SEQ_ELEM( elemType, seq, index )`` -should be used, where the parameter -``elemType`` -is the -type of sequence elements ( -:ref:`CvPoint` -for example), the parameter -``seq`` -is a sequence, and the parameter -``index`` -is the index -of the desired element. The macro checks first whether the desired element -belongs to the first block of the sequence and returns it if it does; -otherwise the macro calls the main function -``GetSeqElem`` -. Negative -indices always cause the -:ref:`GetSeqElem` -call. The function has O(1) -time complexity assuming that the number of blocks is much smaller than the -number of elements. - - -.. index:: GetSeqReaderPos - -.. _GetSeqReaderPos: - -GetSeqReaderPos ---------------- - - - - - - -.. cfunction:: int cvGetSeqReaderPos( CvSeqReader* reader ) - - Returns the current reader position. - - - - - - - :param reader: Reader state - - - -The function returns the current reader position (within 0 ... -``reader->seq->total`` -- 1). - - -.. index:: GetSetElem - -.. _GetSetElem: - -GetSetElem ----------- - - - - - - -.. cfunction:: CvSetElem* cvGetSetElem( const CvSet* setHeader, int index ) - - Finds a set element by its index. - - - - - - - :param setHeader: Set - - - :param index: Index of the set element within a sequence - - - -The function finds a set element by its index. The function returns the pointer to it or 0 if the index is invalid or the corresponding node is free. The function supports negative indices as it uses -:ref:`GetSeqElem` -to locate the node. - - -.. index:: GraphAddEdge - -.. _GraphAddEdge: - -GraphAddEdge ------------- - - - - - - -.. cfunction:: int cvGraphAddEdge( CvGraph* graph, int start_idx, int end_idx, const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL ) - - Adds an edge to a graph. - - - - - - - :param graph: Graph - - - :param start_idx: Index of the starting vertex of the edge - - - :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. - - - :param edge: Optional input parameter, initialization data for the edge - - - :param inserted_edge: Optional output parameter to contain the address of the inserted edge - - - -The function connects two specified vertices. The function returns 1 if the edge has been added successfully, 0 if the edge connecting the two vertices exists already and -1 if either of the vertices was not found, the starting and the ending vertex are the same, or there is some other critical situation. In the latter case (i.e., when the result is negative), the function also reports an error by default. - - -.. index:: GraphAddEdgeByPtr - -.. _GraphAddEdgeByPtr: - -GraphAddEdgeByPtr ------------------ - - - - - - -.. cfunction:: int cvGraphAddEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx, const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL ) - - Adds an edge to a graph by using its pointer. - - - - - - - :param graph: Graph - - - :param start_vtx: Pointer to the starting vertex of the edge - - - :param end_vtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. - - - :param edge: Optional input parameter, initialization data for the edge - - - :param inserted_edge: Optional output parameter to contain the address of the inserted edge within the edge set - - - -The function connects two specified vertices. The -function returns 1 if the edge has been added successfully, 0 if the -edge connecting the two vertices exists already, and -1 if either of the -vertices was not found, the starting and the ending vertex are the same -or there is some other critical situation. In the latter case (i.e., when -the result is negative), the function also reports an error by default. - - -.. index:: GraphAddVtx - -.. _GraphAddVtx: - -GraphAddVtx ------------ - - - - - - -.. cfunction:: int cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx=NULL, CvGraphVtx** inserted_vtx=NULL ) - - Adds a vertex to a graph. - - - - - - - :param graph: Graph - - - :param vtx: Optional input argument used to initialize the added vertex (only user-defined fields beyond ``sizeof(CvGraphVtx)`` are copied) - - - :param inserted_vertex: Optional output argument. If not ``NULL`` , the address of the new vertex is written here. - - - -The function adds a vertex to the graph and returns the vertex index. - - -.. index:: GraphEdgeIdx - -.. _GraphEdgeIdx: - -GraphEdgeIdx ------------- - - - - - - -.. cfunction:: int cvGraphEdgeIdx( CvGraph* graph, CvGraphEdge* edge ) - - Returns the index of a graph edge. - - - - - - - :param graph: Graph - - - :param edge: Pointer to the graph edge - - - -The function returns the index of a graph edge. - - -.. index:: GraphRemoveEdge - -.. _GraphRemoveEdge: - -GraphRemoveEdge ---------------- - - - - - - -.. cfunction:: void cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ) - - Removes an edge from a graph. - - - - - - - :param graph: Graph - - - :param start_idx: Index of the starting vertex of the edge - - - :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. - - - -The function removes the edge connecting two specified vertices. If the vertices are not connected [in that order], the function does nothing. - - -.. index:: GraphRemoveEdgeByPtr - -.. _GraphRemoveEdgeByPtr: - -GraphRemoveEdgeByPtr --------------------- - - - - - - -.. cfunction:: void cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx ) - - Removes an edge from a graph by using its pointer. - - - - - - - :param graph: Graph - - - :param start_vtx: Pointer to the starting vertex of the edge - - - :param end_vtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. - - - -The function removes the edge connecting two specified vertices. If the vertices are not connected [in that order], the function does nothing. - - -.. index:: GraphRemoveVtx - -.. _GraphRemoveVtx: - -GraphRemoveVtx --------------- - - - - - - -.. cfunction:: int cvGraphRemoveVtx( CvGraph* graph, int index ) - - Removes a vertex from a graph. - - - - - - - :param graph: Graph - - - :param vtx_idx: Index of the removed vertex - - - -The function removes a vertex from a graph -together with all the edges incident to it. The function reports an error -if the input vertex does not belong to the graph. The return value is the -number of edges deleted, or -1 if the vertex does not belong to the graph. - - -.. index:: GraphRemoveVtxByPtr - -.. _GraphRemoveVtxByPtr: - -GraphRemoveVtxByPtr -------------------- - - - - - - -.. cfunction:: int cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ) - - Removes a vertex from a graph by using its pointer. - - - - - - - :param graph: Graph - - - :param vtx: Pointer to the removed vertex - - - -The function removes a vertex from the graph by using its pointer together with all the edges incident to it. The function reports an error if the vertex does not belong to the graph. The return value is the number of edges deleted, or -1 if the vertex does not belong to the graph. - - -.. index:: GraphVtxDegree - -.. _GraphVtxDegree: - -GraphVtxDegree --------------- - - - - - - -.. cfunction:: int cvGraphVtxDegree( const CvGraph* graph, int vtxIdx ) - - Counts the number of edges indicent to the vertex. - - - - - - - :param graph: Graph - - - :param vtxIdx: Index of the graph vertex - - - -The function returns the number of edges incident to the specified vertex, both incoming and outgoing. To count the edges, the following code is used: - - - - -:: - - - - CvGraphEdge* edge = vertex->first; int count = 0; - while( edge ) - { - edge = CV_NEXT_GRAPH_EDGE( edge, vertex ); - count++; - } - - -.. - -The macro -``CV_NEXT_GRAPH_EDGE( edge, vertex )`` -returns the edge incident to -``vertex`` -that follows after -``edge`` -. - - -.. index:: GraphVtxDegreeByPtr - -.. _GraphVtxDegreeByPtr: - -GraphVtxDegreeByPtr -------------------- - - - - - - -.. cfunction:: int cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx ) - - Finds an edge in a graph. - - - - - - - :param graph: Graph - - - :param vtx: Pointer to the graph vertex - - - -The function returns the number of edges incident to the specified vertex, both incoming and outcoming. - - - -.. index:: GraphVtxIdx - -.. _GraphVtxIdx: - -GraphVtxIdx ------------ - - - - - - -.. cfunction:: int cvGraphVtxIdx( CvGraph* graph, CvGraphVtx* vtx ) - - Returns the index of a graph vertex. - - - - - - - :param graph: Graph - - - :param vtx: Pointer to the graph vertex - - - -The function returns the index of a graph vertex. - - -.. index:: InitTreeNodeIterator - -.. _InitTreeNodeIterator: - -InitTreeNodeIterator --------------------- - - - - - - -.. cfunction:: void cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator, const void* first, int max_level ) - - Initializes the tree node iterator. - - - - - - - :param tree_iterator: Tree iterator initialized by the function - - - :param first: The initial node to start traversing from - - - :param max_level: The maximal level of the tree ( ``first`` node assumed to be at the first level) to traverse up to. For example, 1 means that only nodes at the same level as ``first`` should be visited, 2 means that the nodes on the same level as ``first`` and their direct children should be visited, and so forth. - - - -The function initializes the tree iterator. The tree is traversed in depth-first order. - - -.. index:: InsertNodeIntoTree - -.. _InsertNodeIntoTree: - -InsertNodeIntoTree ------------------- - - - - - - -.. cfunction:: void cvInsertNodeIntoTree( void* node, void* parent, void* frame ) - - Adds a new node to a tree. - - - - - - - :param node: The inserted node - - - :param parent: The parent node that is already in the tree - - - :param frame: The top level node. If ``parent`` and ``frame`` are the same, the ``v_prev`` field of ``node`` is set to NULL rather than ``parent`` . - - - -The function adds another node into tree. The function does not allocate any memory, it can only modify links of the tree nodes. - - -.. index:: MakeSeqHeaderForArray - -.. _MakeSeqHeaderForArray: - -MakeSeqHeaderForArray ---------------------- - - - - - - -.. cfunction:: CvSeq* cvMakeSeqHeaderForArray( int seq_type, int header_size, int elem_size, void* elements, int total, CvSeq* seq, CvSeqBlock* block ) - - Constructs a sequence header for an array. - - - - - - - :param seq_type: Type of the created sequence - - - :param header_size: Size of the header of the sequence. Parameter sequence must point to the structure of that size or greater - - - :param elem_size: Size of the sequence elements - - - :param elements: Elements that will form a sequence - - - :param total: Total number of elements in the sequence. The number of array elements must be equal to the value of this parameter. - - - :param seq: Pointer to the local variable that is used as the sequence header - - - :param block: Pointer to the local variable that is the header of the single sequence block - - - -The function initializes a sequence -header for an array. The sequence header as well as the sequence block are -allocated by the user (for example, on stack). No data is copied by the -function. The resultant sequence will consists of a single block and -have NULL storage pointer; thus, it is possible to read its elements, -but the attempts to add elements to the sequence will raise an error in -most cases. - - -.. index:: MemStorageAlloc - -.. _MemStorageAlloc: - -MemStorageAlloc ---------------- - - - - - - -.. cfunction:: void* cvMemStorageAlloc( CvMemStorage* storage, size_t size ) - - Allocates a memory buffer in a storage block. - - - - - - - :param storage: Memory storage - - - :param size: Buffer size - - - -The function allocates a memory buffer in -a storage block. The buffer size must not exceed the storage block size, -otherwise a runtime error is raised. The buffer address is aligned by -``CV_STRUCT_ALIGN=sizeof(double)`` -(for the moment) bytes. - - -.. index:: MemStorageAllocString - -.. _MemStorageAllocString: - -MemStorageAllocString ---------------------- - - - - - - -.. cfunction:: CvString cvMemStorageAllocString(CvMemStorage* storage, const char* ptr, int len=-1) - - Allocates a text string in a storage block. - - - - - - -:: - - - - typedef struct CvString - { - int len; - char* ptr; - } - CvString; - - -.. - - - - - :param storage: Memory storage - - - :param ptr: The string - - - :param len: Length of the string (not counting the ending ``NUL`` ) . If the parameter is negative, the function computes the length. - - - -The function creates copy of the string -in memory storage. It returns the structure that contains user-passed -or computed length of the string and pointer to the copied string. - - -.. index:: NextGraphItem - -.. _NextGraphItem: - -NextGraphItem -------------- - - - - - - -.. cfunction:: int cvNextGraphItem( CvGraphScanner* scanner ) - - Executes one or more steps of the graph traversal procedure. - - - - - - - :param scanner: Graph traversal state. It is updated by this function. - - - -The function traverses through the graph -until an event of interest to the user (that is, an event, specified -in the -``mask`` -in the -:ref:`CreateGraphScanner` -call) is met or the -traversal is completed. In the first case, it returns one of the events -listed in the description of the -``mask`` -parameter above and with -the next call it resumes the traversal. In the latter case, it returns -``CV_GRAPH_OVER`` -(-1). When the event is -``CV_GRAPH_VERTEX`` -, -``CV_GRAPH_BACKTRACKING`` -, or -``CV_GRAPH_NEW_TREE`` -, -the currently observed vertex is stored in -``scanner-:math:`>`vtx`` -. And if the -event is edge-related, the edge itself is stored at -``scanner-:math:`>`edge`` -, -the previously visited vertex - at -``scanner-:math:`>`vtx`` -and the other ending -vertex of the edge - at -``scanner-:math:`>`dst`` -. - - -.. index:: NextTreeNode - -.. _NextTreeNode: - -NextTreeNode ------------- - - - - - - -.. cfunction:: void* cvNextTreeNode( CvTreeNodeIterator* tree_iterator ) - - Returns the currently observed node and moves the iterator toward the next node. - - - - - - - :param tree_iterator: Tree iterator initialized by the function - - - -The function returns the currently observed node and then updates the -iterator - moving it toward the next node. In other words, the function -behavior is similar to the -``*p++`` -expression on a typical C -pointer or C++ collection iterator. The function returns NULL if there -are no more nodes. - - - -.. index:: PrevTreeNode - -.. _PrevTreeNode: - -PrevTreeNode ------------- - - - - - - -.. cfunction:: void* cvPrevTreeNode( CvTreeNodeIterator* tree_iterator ) - - Returns the currently observed node and moves the iterator toward the previous node. - - - - - - - :param tree_iterator: Tree iterator initialized by the function - - - -The function returns the currently observed node and then updates -the iterator - moving it toward the previous node. In other words, -the function behavior is similar to the -``*p--`` -expression on a -typical C pointer or C++ collection iterator. The function returns NULL -if there are no more nodes. - - - -.. index:: ReleaseGraphScanner - -.. _ReleaseGraphScanner: - -ReleaseGraphScanner -------------------- - - - - - - -.. cfunction:: void cvReleaseGraphScanner( CvGraphScanner** scanner ) - - Completes the graph traversal procedure. - - - - - - - :param scanner: Double pointer to graph traverser - - - -The function completes the graph traversal procedure and releases the traverser state. - - - - -.. index:: ReleaseMemStorage - -.. _ReleaseMemStorage: - -ReleaseMemStorage ------------------ - - - - - - -.. cfunction:: void cvReleaseMemStorage( CvMemStorage** storage ) - - Releases memory storage. - - - - - - - :param storage: Pointer to the released storage - - - -The function deallocates all storage memory -blocks or returns them to the parent, if any. Then it deallocates the -storage header and clears the pointer to the storage. All child storage -associated with a given parent storage block must be released before the -parent storage block is released. - - -.. index:: RestoreMemStoragePos - -.. _RestoreMemStoragePos: - -RestoreMemStoragePos --------------------- - - - - - - -.. cfunction:: void cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos) - - Restores memory storage position. - - - - - - - :param storage: Memory storage - - - :param pos: New storage top position - - - -The function restores the position of the storage top from the parameter -``pos`` -. This function and the function -``cvClearMemStorage`` -are the only methods to release memory occupied in memory blocks. Note again that there is no way to free memory in the middle of an occupied portion of a storage block. - - - -.. index:: SaveMemStoragePos - -.. _SaveMemStoragePos: - -SaveMemStoragePos ------------------ - - - - - - -.. cfunction:: void cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos) - - Saves memory storage position. - - - - - - - :param storage: Memory storage - - - :param pos: The output position of the storage top - - - -The function saves the current position -of the storage top to the parameter -``pos`` -. The function -``cvRestoreMemStoragePos`` -can further retrieve this position. - - -.. index:: SeqElemIdx - -.. _SeqElemIdx: - -SeqElemIdx ----------- - - - - - - -.. cfunction:: int cvSeqElemIdx( const CvSeq* seq, const void* element, CvSeqBlock** block=NULL ) - - Returns the index of a specific sequence element. - - - - - - - :param seq: Sequence - - - :param element: Pointer to the element within the sequence - - - :param block: Optional argument. If the pointer is not ``NULL`` , the address of the sequence block that contains the element is stored in this location. - - - -The function returns the index of a sequence element or a negative number if the element is not found. - - -.. index:: SeqInsert - -.. _SeqInsert: - -SeqInsert ---------- - - - - - - -.. cfunction:: char* cvSeqInsert( CvSeq* seq, int beforeIndex, void* element=NULL ) - - Inserts an element in the middle of a sequence. - - - - - - - :param seq: Sequence - - - :param beforeIndex: Index before which the element is inserted. Inserting before 0 (the minimal allowed value of the parameter) is equal to :ref:`SeqPushFront` and inserting before ``seq->total`` (the maximal allowed value of the parameter) is equal to :ref:`SeqPush` . - - - :param element: Inserted element - - - -The function shifts the sequence elements from the inserted position to the nearest end of the sequence and copies the -``element`` -content there if the pointer is not NULL. The function returns a pointer to the inserted element. - - - -.. index:: SeqInsertSlice - -.. _SeqInsertSlice: - -SeqInsertSlice --------------- - -.. cfunction:: void cvSeqInsertSlice( CvSeq* seq, int beforeIndex, const CvArr* fromArr ) - - Inserts an array in the middle of a sequence. - - :param seq: Sequence - - :param beforeIndex: Index before which the array is inserted - - :param fromArr: The array to take elements from - - -The function inserts all -``fromArr`` -array elements at the specified position of the sequence. The array -``fromArr`` -can be a matrix or another sequence. - - -.. index:: SeqInvert - -.. _SeqInvert: - -SeqInvert ---------- - -.. cfunction:: void cvSeqInvert( CvSeq* seq ) - - Reverses the order of sequence elements. - - :param seq: Sequence - -The function reverses the sequence in-place - the first element becomes the last one, the last element becomes the first one and so forth. - -.. index:: SeqPop - -.. _SeqPop: - -SeqPop ------- - -.. cfunction:: void cvSeqPop( CvSeq* seq, void* element=NULL ) - - Removes an element from the end of a sequence. - - :param seq: Sequence - - :param element: Optional parameter . If the pointer is not zero, the function copies the removed element to this location. - -The function removes an element from a sequence. The function reports an error if the sequence is already empty. The function has O(1) complexity. - - -.. index:: SeqPopFront - -.. _SeqPopFront: - -SeqPopFront ------------ - -.. cfunction:: void cvSeqPopFront( CvSeq* seq, void* element=NULL ) - - Removes an element from the beginning of a sequence. - - - - - - - :param seq: Sequence - - - :param element: Optional parameter. If the pointer is not zero, the function copies the removed element to this location. - - - -The function removes an element from the beginning of a sequence. The function reports an error if the sequence is already empty. The function has O(1) complexity. - - -.. index:: SeqPopMulti - -.. _SeqPopMulti: - -SeqPopMulti ------------ - - - - - - -.. cfunction:: void cvSeqPopMulti( CvSeq* seq, void* elements, int count, int in_front=0 ) - - Removes several elements from either end of a sequence. - - - - - - - :param seq: Sequence - - - :param elements: Removed elements - - - :param count: Number of elements to pop - - - :param in_front: The flags specifying which end of the modified sequence. - - * **CV_BACK** the elements are added to the end of the sequence - - * **CV_FRONT** the elements are added to the beginning of the sequence - - - - - -The function removes several elements from either end of the sequence. If the number of the elements to be removed exceeds the total number of elements in the sequence, the function removes as many elements as possible. - - -.. index:: SeqPush - -.. _SeqPush: - -SeqPush -------- - - - - - - -.. cfunction:: char* cvSeqPush( CvSeq* seq, void* element=NULL ) - - Adds an element to the end of a sequence. - - - - - - - :param seq: Sequence - - - :param element: Added element - - - -The function adds an element to the end of a sequence and returns a pointer to the allocated element. If the input -``element`` -is NULL, the function simply allocates a space for one more element. - -The following code demonstrates how to create a new sequence using this function: - - - - -:: - - - - CvMemStorage* storage = cvCreateMemStorage(0); - CvSeq* seq = cvCreateSeq( CV_32SC1, /* sequence of integer elements */ - sizeof(CvSeq), /* header size - no extra fields */ - sizeof(int), /* element size */ - storage /* the container storage */ ); - int i; - for( i = 0; i < 100; i++ ) - { - int* added = (int*)cvSeqPush( seq, &i ); - printf( " - } - - ... - /* release memory storage in the end */ - cvReleaseMemStorage( &storage ); - - -.. - -The function has O(1) complexity, but there is a faster method for writing large sequences (see -:ref:`StartWriteSeq` -and related functions). - - - -.. index:: SeqPushFront - -.. _SeqPushFront: - -SeqPushFront ------------- - - - - - - -.. cfunction:: char* cvSeqPushFront( CvSeq* seq, void* element=NULL ) - - Adds an element to the beginning of a sequence. - - - - - - - :param seq: Sequence - - - :param element: Added element - - - -The function is similar to -:ref:`SeqPush` -but it adds the new element to the beginning of the sequence. The function has O(1) complexity. - - -.. index:: SeqPushMulti - -.. _SeqPushMulti: - -SeqPushMulti ------------- - - - - - - -.. cfunction:: void cvSeqPushMulti( CvSeq* seq, void* elements, int count, int in_front=0 ) - - Pushes several elements to either end of a sequence. - - - - - - - :param seq: Sequence - - - :param elements: Added elements - - - :param count: Number of elements to push - - - :param in_front: The flags specifying which end of the modified sequence. - - * **CV_BACK** the elements are added to the end of the sequence - - * **CV_FRONT** the elements are added to the beginning of the sequence - - - - - -The function adds several elements to either -end of a sequence. The elements are added to the sequence in the same -order as they are arranged in the input array but they can fall into -different sequence blocks. - - -.. index:: SeqRemove - -.. _SeqRemove: - -SeqRemove ---------- - - - - - - -.. cfunction:: void cvSeqRemove( CvSeq* seq, int index ) - - Removes an element from the middle of a sequence. - - - - - - - :param seq: Sequence - - - :param index: Index of removed element - - - -The function removes elements with the given -index. If the index is out of range the function reports an error. An -attempt to remove an element from an empty sequence is a special -case of this situation. The function removes an element by shifting -the sequence elements between the nearest end of the sequence and the -``index`` --th position, not counting the latter. - - - -.. index:: SeqRemoveSlice - -.. _SeqRemoveSlice: - -SeqRemoveSlice --------------- - - - - - - -.. cfunction:: void cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) - - Removes a sequence slice. - - - - - - - :param seq: Sequence - - - :param slice: The part of the sequence to remove - - - -The function removes a slice from the sequence. - - -.. index:: SeqSearch - -.. _SeqSearch: - -SeqSearch ---------- - - - - - - -.. cfunction:: char* cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func, int is_sorted, int* elem_idx, void* userdata=NULL ) - - Searches for an element in a sequence. - - - - - - - :param seq: The sequence - - - :param elem: The element to look for - - - :param func: The comparison function that returns negative, zero or positive value depending on the relationships among the elements (see also :ref:`SeqSort` ) - - - :param is_sorted: Whether the sequence is sorted or not - - - :param elem_idx: Output parameter; index of the found element - - - :param userdata: The user parameter passed to the compasion function; helps to avoid global variables in some cases - - - - - - -:: - - - - /* a < b ? -1 : a > b ? 1 : 0 */ - typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); - - -.. - -The function searches for the element in the sequence. If -the sequence is sorted, a binary O(log(N)) search is used; otherwise, a -simple linear search is used. If the element is not found, the function -returns a NULL pointer and the index is set to the number of sequence -elements if a linear search is used, or to the smallest index -``i, seq(i)>elem`` -. - - -.. index:: SeqSlice - -.. _SeqSlice: - -SeqSlice --------- - - - - - - -.. cfunction:: CvSeq* cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage=NULL, int copy_data=0 ) - - Makes a separate header for a sequence slice. - - - - - - - :param seq: Sequence - - - :param slice: The part of the sequence to be extracted - - - :param storage: The destination storage block to hold the new sequence header and the copied data, if any. If it is NULL, the function uses the storage block containing the input sequence. - - - :param copy_data: The flag that indicates whether to copy the elements of the extracted slice ( ``copy_data!=0`` ) or not ( ``copy_data=0`` ) - - - -The function creates a sequence that represents the specified slice of the input sequence. The new sequence either shares the elements with the original sequence or has its own copy of the elements. So if one needs to process a part of sequence but the processing function does not have a slice parameter, the required sub-sequence may be extracted using this function. - - -.. index:: SeqSort - -.. _SeqSort: - -SeqSort -------- - - - - - - -.. cfunction:: void cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata=NULL ) - - Sorts sequence element using the specified comparison function. - - - - - - -:: - - - - /* a < b ? -1 : a > b ? 1 : 0 */ - typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); - - -.. - - - - - :param seq: The sequence to sort - - - :param func: The comparison function that returns a negative, zero, or positive value depending on the relationships among the elements (see the above declaration and the example below) - a similar function is used by ``qsort`` from C runline except that in the latter, ``userdata`` is not used - - - :param userdata: The user parameter passed to the compasion function; helps to avoid global variables in some cases - - - -The function sorts the sequence in-place using the specified criteria. Below is an example of using this function: - - - - -:: - - - - /* Sort 2d points in top-to-bottom left-to-right order */ - static int cmp_func( const void* _a, const void* _b, void* userdata ) - { - CvPoint* a = (CvPoint*)_a; - CvPoint* b = (CvPoint*)_b; - int y_diff = a->y - b->y; - int x_diff = a->x - b->x; - return y_diff ? y_diff : x_diff; - } - - ... - - CvMemStorage* storage = cvCreateMemStorage(0); - CvSeq* seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage ); - int i; - - for( i = 0; i < 10; i++ ) - { - CvPoint pt; - pt.x = rand() - pt.y = rand() - cvSeqPush( seq, &pt ); - } - - cvSeqSort( seq, cmp_func, 0 /* userdata is not used here */ ); - - /* print out the sorted sequence */ - for( i = 0; i < seq->total; i++ ) - { - CvPoint* pt = (CvPoint*)cvSeqElem( seq, i ); - printf( "( - } - - cvReleaseMemStorage( &storage ); - - -.. - - -.. index:: SetAdd - -.. _SetAdd: - -SetAdd ------- - - - - - - -.. cfunction:: int cvSetAdd( CvSet* setHeader, CvSetElem* elem=NULL, CvSetElem** inserted_elem=NULL ) - - Occupies a node in the set. - - - - - - - :param setHeader: Set - - - :param elem: Optional input argument, an inserted element. If not NULL, the function copies the data to the allocated node (the MSB of the first integer field is cleared after copying). - - - :param inserted_elem: Optional output argument; the pointer to the allocated cell - - - -The function allocates a new node, optionally copies -input element data to it, and returns the pointer and the index to the -node. The index value is taken from the lower bits of the -``flags`` -field of the node. The function has O(1) complexity; however, there exists -a faster function for allocating set nodes (see -:ref:`SetNew` -). - - -.. index:: SetNew - -.. _SetNew: - -SetNew ------- - - - - - - -.. cfunction:: CvSetElem* cvSetNew( CvSet* setHeader ) - - Adds an element to a set (fast variant). - - - - - - - :param setHeader: Set - - - -The function is an inline lightweight variant of -:ref:`SetAdd` -. It occupies a new node and returns a pointer to it rather than an index. - - - -.. index:: SetRemove - -.. _SetRemove: - -SetRemove ---------- - - - - - - -.. cfunction:: void cvSetRemove( CvSet* setHeader, int index ) - - Removes an element from a set. - - - - - - - :param setHeader: Set - - - :param index: Index of the removed element - - - -The function removes an element with a specified -index from the set. If the node at the specified location is not occupied, -the function does nothing. The function has O(1) complexity; however, -:ref:`SetRemoveByPtr` -provides a quicker way to remove a set element -if it is located already. - - -.. index:: SetRemoveByPtr - -.. _SetRemoveByPtr: - -SetRemoveByPtr --------------- - - - - - - -.. cfunction:: void cvSetRemoveByPtr( CvSet* setHeader, void* elem ) - - Removes a set element based on its pointer. - - - - - - - :param setHeader: Set - - - :param elem: Removed element - - - -The function is an inline lightweight variant of -:ref:`SetRemove` -that requires an element pointer. The function does not check whether the node is occupied or not - the user should take care of that. - - - -.. index:: SetSeqBlockSize - -.. _SetSeqBlockSize: - -SetSeqBlockSize ---------------- - - - - - - -.. cfunction:: void cvSetSeqBlockSize( CvSeq* seq, int deltaElems ) - - Sets up sequence block size. - - - - - - - :param seq: Sequence - - - :param deltaElems: Desirable sequence block size for elements - - - -The function affects memory allocation -granularity. When the free space in the sequence buffers has run out, -the function allocates the space for -``deltaElems`` -sequence -elements. If this block immediately follows the one previously allocated, -the two blocks are concatenated; otherwise, a new sequence block is -created. Therefore, the bigger the parameter is, the lower the possible -sequence fragmentation, but the more space in the storage block is wasted. When -the sequence is created, the parameter -``deltaElems`` -is set to -the default value of about 1K. The function can be called any time after -the sequence is created and affects future allocations. The function -can modify the passed value of the parameter to meet memory storage -constraints. - - -.. index:: SetSeqReaderPos - -.. _SetSeqReaderPos: - -SetSeqReaderPos ---------------- - - - - - - -.. cfunction:: void cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative=0 ) - - Moves the reader to the specified position. - - - - - - - :param reader: Reader state - - - :param index: The destination position. If the positioning mode is used (see the next parameter), the actual position will be ``index`` mod ``reader->seq->total`` . - - - :param is_relative: If it is not zero, then ``index`` is a relative to the current position - - - -The function moves the read position to an absolute position or relative to the current position. - - - -.. index:: StartAppendToSeq - -.. _StartAppendToSeq: - -StartAppendToSeq ----------------- - - - - - - -.. cfunction:: void cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer ) - - Initializes the process of writing data to a sequence. - - - - - - - :param seq: Pointer to the sequence - - - :param writer: Writer state; initialized by the function - - - -The function initializes the process of -writing data to a sequence. Written elements are added to the end of the -sequence by using the -``CV_WRITE_SEQ_ELEM( written_elem, writer )`` -macro. Note -that during the writing process, other operations on the sequence may -yield an incorrect result or even corrupt the sequence (see description of -:ref:`FlushSeqWriter` -, which helps to avoid some of these problems). - - -.. index:: StartReadSeq - -.. _StartReadSeq: - -StartReadSeq ------------- - - - - - - -.. cfunction:: void cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, int reverse=0 ) - - Initializes the process of sequential reading from a sequence. - - - - - - - :param seq: Sequence - - - :param reader: Reader state; initialized by the function - - - :param reverse: Determines the direction of the sequence traversal. If ``reverse`` is 0, the reader is positioned at the first sequence element; otherwise it is positioned at the last element. - - - -The function initializes the reader state. After -that, all the sequence elements from the first one down to the last one -can be read by subsequent calls of the macro -``CV_READ_SEQ_ELEM( read_elem, reader )`` -in the case of forward reading and by using -``CV_REV_READ_SEQ_ELEM( read_elem, reader )`` -in the case of reverse -reading. Both macros put the sequence element to -``read_elem`` -and -move the reading pointer toward the next element. A circular structure -of sequence blocks is used for the reading process, that is, after the -last element has been read by the macro -``CV_READ_SEQ_ELEM`` -, the -first element is read when the macro is called again. The same applies to -``CV_REV_READ_SEQ_ELEM`` -. There is no function to finish the reading -process, since it neither changes the sequence nor creates any temporary -buffers. The reader field -``ptr`` -points to the current element of -the sequence that is to be read next. The code below demonstrates how -to use the sequence writer and reader. - - - - -:: - - - - CvMemStorage* storage = cvCreateMemStorage(0); - CvSeq* seq = cvCreateSeq( CV_32SC1, sizeof(CvSeq), sizeof(int), storage ); - CvSeqWriter writer; - CvSeqReader reader; - int i; - - cvStartAppendToSeq( seq, &writer ); - for( i = 0; i < 10; i++ ) - { - int val = rand() - CV_WRITE_SEQ_ELEM( val, writer ); - printf(" - } - cvEndWriteSeq( &writer ); - - cvStartReadSeq( seq, &reader, 0 ); - for( i = 0; i < seq->total; i++ ) - { - int val; - #if 1 - CV_READ_SEQ_ELEM( val, reader ); - printf(" - #else /* alternative way, that is prefferable if sequence elements are large, - or their size/type is unknown at compile time */ - printf(" - CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); - #endif - } - ... - - cvReleaseStorage( &storage ); - - -.. - - -.. index:: StartWriteSeq - -.. _StartWriteSeq: - -StartWriteSeq -------------- - - - - - - -.. cfunction:: void cvStartWriteSeq( int seq_flags, int header_size, int elem_size, CvMemStorage* storage, CvSeqWriter* writer ) - - Creates a new sequence and initializes a writer for it. - - - - - - - :param seq_flags: Flags of the created sequence. If the sequence is not passed to any function working with a specific type of sequences, the sequence value may be equal to 0; otherwise the appropriate type must be selected from the list of predefined sequence types. - - - :param header_size: Size of the sequence header. The parameter value may not be less than ``sizeof(CvSeq)`` . If a certain type or extension is specified, it must fit within the base type header. - - - :param elem_size: Size of the sequence elements in bytes; must be consistent with the sequence type. For example, if a sequence of points is created (element type ``CV_SEQ_ELTYPE_POINT`` ), then the parameter ``elem_size`` must be equal to ``sizeof(CvPoint)`` . - - - :param storage: Sequence location - - - :param writer: Writer state; initialized by the function - - - -The function is a combination of -:ref:`CreateSeq` -and -:ref:`StartAppendToSeq` -. The pointer to the -created sequence is stored at -``writer->seq`` -and is also returned by the -:ref:`EndWriteSeq` -function that should be called at the end. - - -.. index:: TreeToNodeSeq - -.. _TreeToNodeSeq: - -TreeToNodeSeq -------------- - - - - - - -.. cfunction:: CvSeq* cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage ) - - Gathers all node pointers to a single sequence. - - - - - - - :param first: The initial tree node - - - :param header_size: Header size of the created sequence (sizeof(CvSeq) is the most frequently used value) - - - :param storage: Container for the sequence - - - -The function puts pointers of all nodes reacheable from -``first`` -into a single sequence. The pointers are written sequentially in the depth-first order. - diff --git a/doc/opencv1/c/core_operations_on_arrays.rst b/doc/opencv1/c/core_operations_on_arrays.rst deleted file mode 100644 index ebfb335769..0000000000 --- a/doc/opencv1/c/core_operations_on_arrays.rst +++ /dev/null @@ -1,7262 +0,0 @@ -Operations on Arrays -==================== - -.. highlight:: c - - - -.. index:: AbsDiff - -.. _AbsDiff: - -AbsDiff -------- - - - - - - -.. cfunction:: void cvAbsDiff(const CvArr* src1, const CvArr* src2, CvArr* dst) - - Calculates absolute difference between two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second source array - - - :param dst: The destination array - - - -The function calculates absolute difference between two arrays. - - - -.. math:: - - \texttt{dst} (i)_c = | \texttt{src1} (I)_c - \texttt{src2} (I)_c| - - -All the arrays must have the same data type and the same size (or ROI size). - - -.. index:: AbsDiffS - -.. _AbsDiffS: - -AbsDiffS --------- - - - - - - -.. cfunction:: void cvAbsDiffS(const CvArr* src, CvArr* dst, CvScalar value) - - Calculates absolute difference between an array and a scalar. - - - - - - -:: - - - - #define cvAbs(src, dst) cvAbsDiffS(src, dst, cvScalarAll(0)) - - -.. - - - - - :param src: The source array - - - :param dst: The destination array - - - :param value: The scalar - - - -The function calculates absolute difference between an array and a scalar. - - - -.. math:: - - \texttt{dst} (i)_c = | \texttt{src} (I)_c - \texttt{value} _c| - - -All the arrays must have the same data type and the same size (or ROI size). - - - -.. index:: Add - -.. _Add: - -Add ---- - - - - - - -.. cfunction:: void cvAdd(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) - - Computes the per-element sum of two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second 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 - - - -The function adds one array to another: - - - - -:: - - - - dst(I)=src1(I)+src2(I) if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). -For types that have limited range this operation is saturating. - - -.. index:: AddS - -.. _AddS: - -AddS ----- - - - - - - -.. cfunction:: void cvAddS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) - - Computes the sum of an array and a scalar. - - - - - - - :param src: The source array - - - :param value: Added scalar - - - :param dst: The destination array - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - - -The function adds a scalar -``value`` -to every element in the source array -``src1`` -and stores the result in -``dst`` -. -For types that have limited range this operation is saturating. - - - - -:: - - - - dst(I)=src(I)+value if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). - - - -.. index:: AddWeighted - -.. _AddWeighted: - -AddWeighted ------------ - - - - - - -.. cfunction:: void cvAddWeighted(const CvArr* src1, double alpha, const CvArr* src2, double beta, double gamma, CvArr* dst) - - Computes the weighted sum of two arrays. - - - - - - - :param src1: The first source array - - - :param alpha: Weight for the first array elements - - - :param src2: The second source array - - - :param beta: Weight for the second array elements - - - :param dst: The destination array - - - :param gamma: Scalar, added to each sum - - - -The function calculates the weighted sum of two arrays as follows: - - - - -:: - - - - dst(I)=src1(I)*alpha+src2(I)*beta+gamma - - -.. - -All the arrays must have the same type and the same size (or ROI size). -For types that have limited range this operation is saturating. - - - -.. index:: And - -.. _And: - -And ---- - - - - - - -.. cfunction:: void cvAnd(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) - - Calculates per-element bit-wise conjunction of two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second 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 - - - -The function calculates per-element bit-wise logical conjunction of two arrays: - - - - -:: - - - - dst(I)=src1(I)&src2(I) if mask(I)!=0 - - -.. - -In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - -.. index:: AndS - -.. _AndS: - -AndS ----- - - - - - - -.. cfunction:: void cvAndS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) - - Calculates per-element bit-wise conjunction of an array and a scalar. - - - - - - - :param src: The source array - - - :param value: Scalar to use in the operation - - - :param dst: The destination array - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - - -The function calculates per-element bit-wise conjunction of an array and a scalar: - - - - -:: - - - - dst(I)=src(I)&value if mask(I)!=0 - - -.. - -Prior to the actual operation, the scalar is converted to the same type as that of the array(s). In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - -The following sample demonstrates how to calculate the absolute value of floating-point array elements by clearing the most-significant bit: - - - - -:: - - - - float a[] = { -1, 2, -3, 4, -5, 6, -7, 8, -9 }; - CvMat A = cvMat(3, 3, CV_32F, &a); - int i, absMask = 0x7fffffff; - cvAndS(&A, cvRealScalar(*(float*)&absMask), &A, 0); - for(i = 0; i < 9; i++ ) - printf(" - - -.. - -The code should print: - - - - -:: - - - - 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 - - -.. - - -.. index:: Avg - -.. _Avg: - -Avg ---- - - - - - - -.. cfunction:: CvScalar cvAvg(const CvArr* arr, const CvArr* mask=NULL) - - Calculates average (mean) of array elements. - - - - - - - :param arr: The array - - - :param mask: The optional operation mask - - - -The function calculates the average value -``M`` -of array elements, independently for each channel: - - - -.. math:: - - \begin{array}{l} N = \sum _I ( \texttt{mask} (I) \ne 0) \\ M_c = \frac{\sum_{I, \, \texttt{mask}(I) \ne 0} \texttt{arr} (I)_c}{N} \end{array} - - -If the array is -``IplImage`` -and COI is set, the function processes the selected channel only and stores the average to the first scalar component -:math:`S_0` -. - - -.. index:: AvgSdv - -.. _AvgSdv: - -AvgSdv ------- - - - - - - -.. cfunction:: void cvAvgSdv(const CvArr* arr, CvScalar* mean, CvScalar* stdDev, const CvArr* mask=NULL) - - Calculates average (mean) of array elements. - - - - - - - :param arr: The array - - - :param mean: Pointer to the output mean value, may be NULL if it is not needed - - - :param stdDev: Pointer to the output standard deviation - - - :param mask: The optional operation mask - - - -The function calculates the average value and standard deviation of array elements, independently for each channel: - - - -.. math:: - - \begin{array}{l} N = \sum _I ( \texttt{mask} (I) \ne 0) \\ mean_c = \frac{1}{N} \, \sum _{ I, \, \texttt{mask} (I) \ne 0} \texttt{arr} (I)_c \\ stdDev_c = \sqrt{\frac{1}{N} \, \sum_{ I, \, \texttt{mask}(I) \ne 0} ( \texttt{arr} (I)_c - mean_c)^2} \end{array} - - -If the array is -``IplImage`` -and COI is set, the function processes the selected channel only and stores the average and standard deviation to the first components of the output scalars ( -:math:`mean_0` -and -:math:`stdDev_0` -). - - -.. index:: CalcCovarMatrix - -.. _CalcCovarMatrix: - -CalcCovarMatrix ---------------- - - - - - - -.. cfunction:: void cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* covMat, CvArr* avg, int flags) - - Calculates covariance matrix of a set of vectors. - - - - - - - :param vects: The input vectors, all of which must have the same type and the same size. The vectors do not have to be 1D, they can be 2D (e.g., images) and so forth - - - :param count: The number of input vectors - - - :param covMat: The output covariance matrix that should be floating-point and square - - - :param avg: The input or output (depending on the flags) array - the mean (average) vector of the input vectors - - - :param flags: The operation flags, a combination of the following values - - * **CV_COVAR_SCRAMBLED** The output covariance matrix is calculated as: - - .. math:: - - \texttt{scale} * [ \texttt{vects} [0]- \texttt{avg} , \texttt{vects} [1]- \texttt{avg} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{avg} , \texttt{vects} [1]- \texttt{avg} ,...] - - , - that is, the covariance matrix is :math:`\texttt{count} \times \texttt{count}` . - 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 will - match the eigenvalues of the true covariance matrix and the "true" - eigenvectors can be easily calculated from the eigenvectors of the - "scrambled" covariance matrix. - - * **CV_COVAR_NORMAL** The output covariance matrix is calculated as: - - .. math:: - - \texttt{scale} * [ \texttt{vects} [0]- \texttt{avg} , \texttt{vects} [1]- \texttt{avg} ,...] \cdot [ \texttt{vects} [0]- \texttt{avg} , \texttt{vects} [1]- \texttt{avg} ,...]^T - - , - that is, ``covMat`` will be a covariance matrix - with the same linear size as the total number of elements in each - input vector. One and only one of ``CV_COVAR_SCRAMBLED`` and ``CV_COVAR_NORMAL`` must be specified - - * **CV_COVAR_USE_AVG** If the flag is specified, the function does not calculate ``avg`` from the input vectors, but, instead, uses the passed ``avg`` vector. This is useful if ``avg`` has been already calculated somehow, or if the covariance matrix is calculated by parts - in this case, ``avg`` is not a mean vector of the input sub-set of vectors, but rather the mean vector of the whole set. - - * **CV_COVAR_SCALE** If the flag is specified, the covariance matrix is scaled. In the "normal" mode ``scale`` is '1./count'; 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'). - - - * **CV_COVAR_ROWS** Means that all the input vectors are stored as rows of a single matrix, ``vects[0]`` . ``count`` is ignored in this case, and ``avg`` should be a single-row vector of an appropriate size. - - * **CV_COVAR_COLS** Means that all the input vectors are stored as columns of a single matrix, ``vects[0]`` . ``count`` is ignored in this case, and ``avg`` should be a single-column vector of an appropriate size. - - - - - - -The function calculates the covariance matrix -and, optionally, the mean vector of the set of input vectors. The function -can be used for PCA, for comparing vectors using Mahalanobis distance and so forth. - - -.. index:: CartToPolar - -.. _CartToPolar: - -CartToPolar ------------ - - - - - - -.. cfunction:: void cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude, CvArr* angle=NULL, int angleInDegrees=0) - - Calculates the magnitude and/or angle of 2d vectors. - - - - - - - :param x: The array of x-coordinates - - - :param y: The array of y-coordinates - - - :param magnitude: The destination array of magnitudes, may be set to NULL if it is not needed - - - :param angle: The destination array of angles, may be set to NULL if it is not needed. The angles are measured in radians :math:`(0` to :math:`2 \pi )` or in degrees (0 to 360 degrees). - - - :param angleInDegrees: The flag indicating whether the angles are measured in radians, which is default mode, or in degrees - - - -The function calculates either the magnitude, angle, or both of every 2d vector (x(I),y(I)): - - - - -:: - - - - - magnitude(I)=sqrt(x(I)^2^+y(I)^2^ ), - angle(I)=atan(y(I)/x(I) ) - - - -.. - -The angles are calculated with 0.1 degree accuracy. For the (0,0) point, the angle is set to 0. - - -.. index:: Cbrt - -.. _Cbrt: - -Cbrt ----- - - - - - - -.. cfunction:: float cvCbrt(float value) - - Calculates the cubic root - - - - - - - :param value: The input floating-point value - - - -The function calculates the cubic root of the argument, and normally it is faster than -``pow(value,1./3)`` -. In addition, negative arguments are handled properly. Special values ( -:math:`\pm \infty` -, NaN) are not handled. - - -.. index:: ClearND - -.. _ClearND: - -ClearND -------- - - - - - - -.. cfunction:: void cvClearND(CvArr* arr, int* idx) - - Clears a specific array element. - - - - - - :param arr: Input array - - - :param idx: Array of the element indices - - - -The function -:ref:`ClearND` -clears (sets to zero) a specific element of a dense array or deletes the element of a sparse array. If the sparse array element does not exists, the function does nothing. - - -.. index:: CloneImage - -.. _CloneImage: - -CloneImage ----------- - - - - - - -.. cfunction:: IplImage* cvCloneImage(const IplImage* image) - - Makes a full copy of an image, including the header, data, and ROI. - - - - - - - :param image: The original image - - - -The returned -``IplImage*`` -points to the image copy. - - -.. index:: CloneMat - -.. _CloneMat: - -CloneMat --------- - - - - - - -.. cfunction:: CvMat* cvCloneMat(const CvMat* mat) - - Creates a full matrix copy. - - - - - - - :param mat: Matrix to be copied - - - -Creates a full copy of a matrix and returns a pointer to the copy. - - -.. index:: CloneMatND - -.. _CloneMatND: - -CloneMatND ----------- - - - - - - -.. cfunction:: CvMatND* cvCloneMatND(const CvMatND* mat) - - Creates full copy of a multi-dimensional array and returns a pointer to the copy. - - - - - - - :param mat: Input array - - - - -.. index:: CloneSparseMat - -.. _CloneSparseMat: - -CloneSparseMat --------------- - - - - - - -.. cfunction:: CvSparseMat* cvCloneSparseMat(const CvSparseMat* mat) - - Creates full copy of sparse array. - - - - - - - :param mat: Input array - - - -The function creates a copy of the input array and returns pointer to the copy. - -.. index:: Cmp - -.. _Cmp: - -Cmp ---- - - - - - - -.. cfunction:: void cvCmp(const CvArr* src1, const CvArr* src2, CvArr* dst, int cmpOp) - - Performs per-element comparison of two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second source array. Both source arrays must have a single channel. - - - :param dst: The destination array, must have 8u or 8s type - - - :param cmpOp: The flag specifying the relation between the elements to be checked - - - * **CV_CMP_EQ** src1(I) "equal to" value - - - * **CV_CMP_GT** src1(I) "greater than" value - - - * **CV_CMP_GE** src1(I) "greater or equal" value - - - * **CV_CMP_LT** src1(I) "less than" value - - - * **CV_CMP_LE** src1(I) "less or equal" value - - - * **CV_CMP_NE** src1(I) "not equal" value - - - - - -The function compares the corresponding elements of two arrays and fills the destination mask array: - - - - -:: - - - - dst(I)=src1(I) op src2(I), - - -.. - -``dst(I)`` -is set to 0xff (all -``1`` --bits) if the specific relation between the elements is true and 0 otherwise. All the arrays must have the same type, except the destination, and the same size (or ROI size) - - -.. index:: CmpS - -.. _CmpS: - -CmpS ----- - - - - - - -.. cfunction:: void cvCmpS(const CvArr* src, double value, CvArr* dst, int cmpOp) - - Performs per-element comparison of an array and a scalar. - - - - - - - :param src: The source array, must have a single channel - - - :param value: The scalar value to compare each array element with - - - :param dst: The destination array, must have 8u or 8s type - - - :param cmpOp: The flag specifying the relation between the elements to be checked - - - * **CV_CMP_EQ** src1(I) "equal to" value - - - * **CV_CMP_GT** src1(I) "greater than" value - - - * **CV_CMP_GE** src1(I) "greater or equal" value - - - * **CV_CMP_LT** src1(I) "less than" value - - - * **CV_CMP_LE** src1(I) "less or equal" value - - - * **CV_CMP_NE** src1(I) "not equal" value - - - - - -The function compares the corresponding elements of an array and a scalar and fills the destination mask array: - - - - -:: - - - - dst(I)=src(I) op scalar - - -.. - -where -``op`` -is -:math:`=,\; >,\; \ge,\; <,\; \le\; or\; \ne` -. - -``dst(I)`` -is set to 0xff (all -``1`` --bits) if the specific relation between the elements is true and 0 otherwise. All the arrays must have the same size (or ROI size). - - -.. index:: ConvertScale - -.. _ConvertScale: - -ConvertScale ------------- - - - - - - -.. cfunction:: void cvConvertScale(const CvArr* src, CvArr* dst, double scale=1, double shift=0) - - Converts one array to another with optional linear transformation. - - - - - - -:: - - - - #define cvCvtScale cvConvertScale - #define cvScale cvConvertScale - #define cvConvert(src, dst ) cvConvertScale((src), (dst), 1, 0 ) - - -.. - - - - - :param src: Source array - - - :param dst: Destination array - - - :param scale: Scale factor - - - :param shift: Value added to the scaled source array elements - - - -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: - - - -.. math:: - - \texttt{dst} (I) = \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...) - - -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. - -In the case of -``scale=1, shift=0`` -no prescaling is done. This is a specially -optimized case and it has the appropriate -:ref:`Convert` -name. If -source and destination array types have equal types, this is also a -special case that can be used to scale and shift a matrix or an image -and that is caled -:ref:`Scale` -. - - - -.. index:: ConvertScaleAbs - -.. _ConvertScaleAbs: - -ConvertScaleAbs ---------------- - - - - - - -.. cfunction:: void cvConvertScaleAbs(const CvArr* src, CvArr* dst, double scale=1, double shift=0) - - Converts input array elements to another 8-bit unsigned integer with optional linear transformation. - - - - - - - :param src: Source array - - - :param dst: Destination array (should have 8u depth) - - - :param scale: ScaleAbs factor - - - :param shift: Value added to the scaled source array elements - - - -The function is similar to -:ref:`ConvertScale` -, but it stores absolute values of the conversion results: - - - -.. math:: - - \texttt{dst} (I) = | \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...)| - - -The function supports only destination arrays of 8u (8-bit unsigned integers) type; for other types the function can be emulated by a combination of -:ref:`ConvertScale` -and -:ref:`Abs` -functions. - - -.. index:: CvtScaleAbs - -.. _CvtScaleAbs: - -CvtScaleAbs ------------ - - - - - - -.. cfunction:: void cvCvtScaleAbs(const CvArr* src, CvArr* dst, double scale=1, double shift=0) - - Converts input array elements to another 8-bit unsigned integer with optional linear transformation. - - - - - - - :param src: Source array - - - :param dst: Destination array (should have 8u depth) - - - :param scale: ScaleAbs factor - - - :param shift: Value added to the scaled source array elements - - - -The function is similar to -:ref:`ConvertScale` -, but it stores absolute values of the conversion results: - - - -.. math:: - - \texttt{dst} (I) = | \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...)| - - -The function supports only destination arrays of 8u (8-bit unsigned integers) type; for other types the function can be emulated by a combination of -:ref:`ConvertScale` -and -:ref:`Abs` -functions. - - -.. index:: Copy - -.. _Copy: - -Copy ----- - - - - - - -.. cfunction:: void cvCopy(const CvArr* src, CvArr* dst, const CvArr* mask=NULL) - - Copies one array to another. - - - - - - - :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 - - - -The function copies selected elements from an input array to an output array: - - - -.. math:: - - \texttt{dst} (I)= \texttt{src} (I) \quad \text{if} \quad \texttt{mask} (I) \ne 0. - - -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). - - -.. index:: CountNonZero - -.. _CountNonZero: - -CountNonZero ------------- - - - - - - -.. cfunction:: int cvCountNonZero(const CvArr* arr) - - Counts non-zero array elements. - - - - - - - :param arr: The array must be a single-channel array or a multi-channel image with COI set - - - -The function returns the number of non-zero elements in arr: - - - -.. math:: - - \sum _I ( \texttt{arr} (I) \ne 0) - - -In the case of -``IplImage`` -both ROI and COI are supported. - - - -.. index:: CreateData - -.. _CreateData: - -CreateData ----------- - - - - - - -.. cfunction:: void cvCreateData(CvArr* arr) - - Allocates array data - - - - - - - :param arr: Array header - - - -The function allocates image, matrix or -multi-dimensional array data. Note that in the case of matrix types OpenCV -allocation functions are used and in the case of IplImage they are used -unless -``CV_TURN_ON_IPL_COMPATIBILITY`` -was called. In the -latter case IPL functions are used to allocate the data. - - -.. index:: CreateImage - -.. _CreateImage: - -CreateImage ------------ - - - - - - -.. cfunction:: IplImage* cvCreateImage(CvSize size, int depth, int channels) - - Creates an image header and allocates the image data. - - - - - - - :param size: Image width and height - - - :param depth: Bit depth of image elements. See :ref:`IplImage` for valid depths. - - - :param channels: Number of channels per pixel. See :ref:`IplImage` for details. This function only creates images with interleaved channels. - - - -This call is a shortened form of - - - -:: - - - - header = cvCreateImageHeader(size, depth, channels); - cvCreateData(header); - - -.. - - -.. index:: CreateImageHeader - -.. _CreateImageHeader: - -CreateImageHeader ------------------ - - - - - - -.. cfunction:: IplImage* cvCreateImageHeader(CvSize size, int depth, int channels) - - Creates an image header but does not allocate the image data. - - - - - - - :param size: Image width and height - - - :param depth: Image depth (see :ref:`CreateImage` ) - - - :param channels: Number of channels (see :ref:`CreateImage` ) - - - -This call is an analogue of - - - -:: - - - - hdr=iplCreateImageHeader(channels, 0, depth, - channels == 1 ? "GRAY" : "RGB", - channels == 1 ? "GRAY" : channels == 3 ? "BGR" : - channels == 4 ? "BGRA" : "", - IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL, 4, - size.width, size.height, - 0,0,0,0); - - -.. - -but it does not use IPL functions by default (see the -``CV_TURN_ON_IPL_COMPATIBILITY`` -macro). - -.. index:: CreateMat - -.. _CreateMat: - -CreateMat ---------- - - - - - - -.. cfunction:: CvMat* cvCreateMat( int rows, int cols, int type) - - Creates a matrix header and allocates the matrix data. - - - - - - - :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. - - - -This is the concise form for: - - - - -:: - - - - CvMat* mat = cvCreateMatHeader(rows, cols, type); - cvCreateData(mat); - - -.. - - -.. index:: CreateMatHeader - -.. _CreateMatHeader: - -CreateMatHeader ---------------- - - - - - - -.. cfunction:: CvMat* cvCreateMatHeader( int rows, int cols, int type) - - Creates a matrix header but does not allocate the matrix data. - - - - - - - :param rows: Number of rows in the matrix - - - :param cols: Number of columns in the matrix - - - :param type: Type of the matrix elements, see :ref:`CreateMat` - - - -The function allocates a new matrix header and returns a pointer to it. The matrix data can then be allocated using -:ref:`CreateData` -or set explicitly to user-allocated data via -:ref:`SetData` -. - - -.. index:: CreateMatND - -.. _CreateMatND: - -CreateMatND ------------ - - - - - - -.. cfunction:: CvMatND* cvCreateMatND( int dims, const int* sizes, int type) - - Creates the header and allocates the data for a multi-dimensional dense array. - - - - - - - :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 :ref:`CreateMat` . - - - -This is a short form for: - - - - -:: - - - - CvMatND* mat = cvCreateMatNDHeader(dims, sizes, type); - cvCreateData(mat); - - -.. - - -.. index:: CreateMatNDHeader - -.. _CreateMatNDHeader: - -CreateMatNDHeader ------------------ - - - - - - -.. cfunction:: CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type) - - Creates a new matrix header but does not allocate the matrix data. - - - - - - - :param dims: Number of array dimensions - - - :param sizes: Array of dimension sizes - - - :param type: Type of array elements, see :ref:`CreateMat` - - - -The function allocates a header for a multi-dimensional dense array. The array data can further be allocated using -:ref:`CreateData` -or set explicitly to user-allocated data via -:ref:`SetData` -. - - -.. index:: CreateSparseMat - -.. _CreateSparseMat: - -CreateSparseMat ---------------- - - - - - - -.. cfunction:: CvSparseMat* cvCreateSparseMat(int dims, const int* sizes, int type) - - Creates sparse array. - - - - - - - :param dims: Number of array dimensions. In contrast to the dense matrix, the number of dimensions is practically unlimited (up to :math:`2^{16}` ). - - - :param sizes: Array of dimension sizes - - - :param type: Type of array elements. The same as for CvMat - - - -The function allocates a multi-dimensional sparse array. Initially the array contain no elements, that is -:ref:`Get` -or -:ref:`GetReal` -returns zero for every index. - -.. index:: CrossProduct - -.. _CrossProduct: - -CrossProduct ------------- - - - - - - -.. cfunction:: void cvCrossProduct(const CvArr* src1, const CvArr* src2, CvArr* dst) - - Calculates the cross product of two 3D vectors. - - - - - - - :param src1: The first source vector - - - :param src2: The second source vector - - - :param dst: The destination vector - - - -The function calculates the cross product of two 3D vectors: - - - -.. math:: - - \texttt{dst} = \texttt{src1} \times \texttt{src2} - - -or: - - -.. math:: - - \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} - - - -CvtPixToPlane -------------- - - -Synonym for -:ref:`Split` -. - - -.. index:: DCT - -.. _DCT: - -DCT ---- - - - - - - -.. cfunction:: void cvDCT(const CvArr* src, CvArr* dst, int flags) - - Performs a forward or inverse Discrete Cosine transform of a 1D or 2D floating-point array. - - - - - - - :param src: Source array, real 1D or 2D array - - - :param dst: Destination array of the same size and same type as the source - - - :param flags: Transformation flags, a combination of the following values - - * **CV_DXT_FORWARD** do a forward 1D or 2D transform. - - * **CV_DXT_INVERSE** do an inverse 1D or 2D transform. - - * **CV_DXT_ROWS** do a forward or inverse transform of every individual row of the input matrix. This flag allows user to transform multiple vectors simultaneously and can be used to decrease the overhead (which is sometimes several times larger than the processing itself), to do 3D and higher-dimensional transforms and so forth. - - - - - -The function performs a forward or inverse transform of a 1D or 2D floating-point array: - -Forward Cosine transform of 1D vector of -:math:`N` -elements: - - -.. math:: - - Y = C^{(N)} \cdot X - - -where - - -.. math:: - - C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right ) - - -and -:math:`\alpha_0=1` -, -:math:`\alpha_j=2` -for -:math:`j > 0` -. - -Inverse Cosine transform of 1D vector of N elements: - - -.. math:: - - X = \left (C^{(N)} \right )^{-1} \cdot Y = \left (C^{(N)} \right )^T \cdot Y - - -(since -:math:`C^{(N)}` -is orthogonal matrix, -:math:`C^{(N)} \cdot \left(C^{(N)}\right)^T = I` -) - -Forward Cosine transform of 2D -:math:`M \times N` -matrix: - - -.. math:: - - Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T - - -Inverse Cosine transform of 2D vector of -:math:`M \times N` -elements: - - -.. math:: - - X = \left (C^{(N)} \right )^T \cdot X \cdot C^{(N)} - - - -.. index:: DFT - -.. _DFT: - -DFT ---- - - - - - - -.. cfunction:: void cvDFT(const CvArr* src, CvArr* dst, int flags, int nonzeroRows=0) - - Performs a forward or inverse Discrete Fourier transform of a 1D or 2D floating-point array. - - - - - - - :param src: Source array, real or complex - - - :param dst: Destination array of the same size and same type as the source - - - :param flags: Transformation flags, a combination of the following values - - * **CV_DXT_FORWARD** do a forward 1D or 2D transform. The result is not scaled. - - * **CV_DXT_INVERSE** do an inverse 1D or 2D transform. The result is not scaled. ``CV_DXT_FORWARD`` and ``CV_DXT_INVERSE`` are mutually exclusive, of course. - - * **CV_DXT_SCALE** scale the result: divide it by the number of array elements. Usually, it is combined with ``CV_DXT_INVERSE`` , and one may use a shortcut ``CV_DXT_INV_SCALE`` . - - * **CV_DXT_ROWS** do a forward or inverse transform of every individual row of the input matrix. This flag allows the user to transform multiple vectors simultaneously and can be used to decrease the overhead (which is sometimes several times larger than the processing itself), to do 3D and higher-dimensional transforms and so forth. - - * **CV_DXT_INVERSE_SCALE** same as ``CV_DXT_INVERSE + CV_DXT_SCALE`` - - - - - :param nonzeroRows: Number of nonzero rows in the source array - (in the case of a forward 2d transform), or a number of rows of interest in - the destination array (in the case of an inverse 2d transform). If the value - is negative, zero, or greater than the total number of rows, it is - ignored. The parameter can be used to speed up 2d convolution/correlation - when computing via DFT. See the example below. - - - -The function performs a forward or inverse transform of a 1D or 2D floating-point array: - - -Forward Fourier transform of 1D vector of N elements: - - -.. math:: - - y = F^{(N)} \cdot x, where F^{(N)}_{jk}=exp(-i \cdot 2 \pi \cdot j \cdot k/N) - - -, - - -.. math:: - - i=sqrt(-1) - - -Inverse Fourier transform of 1D vector of N elements: - - -.. math:: - - x'= (F^{(N)})^{-1} \cdot y = conj(F^(N)) \cdot y - x = (1/N) \cdot x - - -Forward Fourier transform of 2D vector of M -:math:`\times` -N elements: - - -.. math:: - - Y = F^{(M)} \cdot X \cdot F^{(N)} - - -Inverse Fourier transform of 2D vector of M -:math:`\times` -N elements: - - -.. math:: - - X'= conj(F^{(M)}) \cdot Y \cdot conj(F^{(N)}) - X = (1/(M \cdot N)) \cdot X' - - -In the case of real (single-channel) data, the packed format, borrowed from IPL, is used to represent the result of a forward Fourier transform or input for an inverse Fourier transform: - - - -.. math:: - - \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} - - -Note: the last column is present if -``N`` -is even, the last row is present if -``M`` -is even. -In the case of 1D real transform the result looks like the first row of the above matrix. - -Here is the example of how to compute 2D convolution using DFT. - - - - -:: - - - - CvMat* A = cvCreateMat(M1, N1, CVg32F); - CvMat* B = cvCreateMat(M2, N2, A->type); - - // it is also possible to have only abs(M2-M1)+1 times abs(N2-N1)+1 - // part of the full convolution result - CvMat* conv = cvCreateMat(A->rows + B->rows - 1, A->cols + B->cols - 1, - A->type); - - // initialize A and B - ... - - int dftgM = cvGetOptimalDFTSize(A->rows + B->rows - 1); - int dftgN = cvGetOptimalDFTSize(A->cols + B->cols - 1); - - CvMat* dftgA = cvCreateMat(dft_M, dft_N, A->type); - CvMat* dftgB = cvCreateMat(dft_M, dft_N, B->type); - CvMat tmp; - - // copy A to dftgA and pad dft_A with zeros - cvGetSubRect(dftgA, &tmp, cvRect(0,0,A->cols,A->rows)); - cvCopy(A, &tmp); - cvGetSubRect(dftgA, &tmp, cvRect(A->cols,0,dft_A->cols - A->cols,A->rows)); - cvZero(&tmp); - // no need to pad bottom part of dftgA with zeros because of - // use nonzerogrows parameter in cvDFT() call below - - cvDFT(dftgA, dft_A, CV_DXT_FORWARD, A->rows); - - // repeat the same with the second array - cvGetSubRect(dftgB, &tmp, cvRect(0,0,B->cols,B->rows)); - cvCopy(B, &tmp); - cvGetSubRect(dftgB, &tmp, cvRect(B->cols,0,dft_B->cols - B->cols,B->rows)); - cvZero(&tmp); - // no need to pad bottom part of dftgB with zeros because of - // use nonzerogrows parameter in cvDFT() call below - - cvDFT(dftgB, dft_B, CV_DXT_FORWARD, B->rows); - - cvMulSpectrums(dftgA, dft_B, dft_A, 0 /* or CV_DXT_MUL_CONJ to get - correlation rather than convolution */); - - cvDFT(dftgA, dft_A, CV_DXT_INV_SCALE, conv->rows); // calculate only - // the top part - cvGetSubRect(dftgA, &tmp, cvRect(0,0,conv->cols,conv->rows)); - - cvCopy(&tmp, conv); - - -.. - - -.. index:: DecRefData - -.. _DecRefData: - -DecRefData ----------- - - - - - - -.. cfunction:: void cvDecRefData(CvArr* arr) - - Decrements an array data reference counter. - - - - - - - :param arr: Pointer to an array header - - - -The function decrements the data reference counter in a -:ref:`CvMat` -or -:ref:`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 -:ref:`CreateData` -function. The counter will be NULL in other cases such as: -external data was assigned to the header using -:ref:`SetData` -, the matrix -header is part of a larger matrix or image, or the header was converted from an image or n-dimensional matrix header. - - -.. index:: Det - -.. _Det: - -Det ---- - - - - - - -.. cfunction:: double cvDet(const CvArr* mat) - - Returns the determinant of a matrix. - - - - - - - :param mat: The source matrix - - - -The function returns the determinant of the square matrix -``mat`` -. The direct method is used for small matrices and Gaussian elimination is used for larger matrices. For symmetric positive-determined matrices, it is also possible to run -:ref:`SVD` -with -:math:`U = V = 0` -and then calculate the determinant as a product of the diagonal elements of -:math:`W` -. - - -.. index:: Div - -.. _Div: - -Div ---- - - - - - - -.. cfunction:: void cvDiv(const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1) - - Performs per-element division of two arrays. - - - - - - - :param src1: The first source array. If the pointer is NULL, the array is assumed to be all 1's. - - - :param src2: The second source array - - - :param dst: The destination array - - - :param scale: Optional scale factor - - - -The function divides one array by another: - - - -.. math:: - - \texttt{dst} (I)= \fork{\texttt{scale} \cdot \texttt{src1}(I)/\texttt{src2}(I)}{if \texttt{src1} is not \texttt{NULL}}{\texttt{scale}/\texttt{src2}(I)}{otherwise} - - -All the arrays must have the same type and the same size (or ROI size). - - - -.. index:: DotProduct - -.. _DotProduct: - -DotProduct ----------- - - - - - - -.. cfunction:: double cvDotProduct(const CvArr* src1, const CvArr* src2) - - Calculates the dot product of two arrays in Euclidian metrics. - - - - - - - :param src1: The first source array - - - :param src2: The second source array - - - -The function calculates and returns the Euclidean dot product of two arrays. - - - -.. math:: - - src1 \bullet src2 = \sum _I ( \texttt{src1} (I) \texttt{src2} (I)) - - -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 -:math:`||\texttt{a}||^2` -. -The function can process multi-dimensional arrays, row by row, layer by layer, and so on. - - -.. index:: EigenVV - -.. _EigenVV: - -EigenVV -------- - - - - - - -.. cfunction:: void cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps=0, int lowindex = -1, int highindex = -1) - - Computes eigenvalues and eigenvectors of a symmetric matrix. - - - - - - - :param mat: The input symmetric square matrix, modified during the processing - - - :param evects: The output matrix of eigenvectors, stored as subsequent rows - - - :param evals: The output vector of eigenvalues, stored in the descending order (order of eigenvalues and eigenvectors is syncronized, of course) - - - :param eps: Accuracy of diagonalization. Typically, ``DBL_EPSILON`` (about :math:`10^{-15}` ) works well. - THIS PARAMETER IS CURRENTLY IGNORED. - - - :param lowindex: Optional index of largest eigenvalue/-vector to calculate. - (See below.) - - - :param highindex: Optional index of smallest eigenvalue/-vector to calculate. - (See below.) - - - -The function computes the eigenvalues and eigenvectors of matrix -``A`` -: - - - - -:: - - - - mat*evects(i,:)' = evals(i)*evects(i,:)' (in MATLAB notation) - - -.. - -If either low- or highindex is supplied the other is required, too. -Indexing is 0-based. Example: To calculate the largest eigenvector/-value set -``lowindex=highindex=0`` -. To calculate all the eigenvalues, leave -``lowindex=highindex=-1`` -. -For legacy reasons this function always returns a square matrix the same size -as the source matrix with eigenvectors and a vector the length of the source -matrix with eigenvalues. The selected eigenvectors/-values are always in the -first highindex - lowindex + 1 rows. - -The contents of matrix -``A`` -is destroyed by the function. - -Currently the function is slower than -:ref:`SVD` -yet less accurate, -so if -``A`` -is known to be positively-defined (for example, it -is a covariance matrix)it is recommended to use -:ref:`SVD` -to find -eigenvalues and eigenvectors of -``A`` -, especially if eigenvectors -are not required. - - -.. index:: Exp - -.. _Exp: - -Exp ---- - - - - - - -.. cfunction:: void cvExp(const CvArr* src, CvArr* dst) - - Calculates the exponent of every array element. - - - - - - - :param src: The source array - - - :param dst: The destination array, it should have ``double`` type or the same type as the source - - - -The function calculates the exponent of every element of the input array: - - - -.. math:: - - \texttt{dst} [I] = e^{ \texttt{src} (I)} - - -The maximum relative error is about -:math:`7 \times 10^{-6}` -. Currently, the function converts denormalized values to zeros on output. - - -.. index:: FastArctan - -.. _FastArctan: - -FastArctan ----------- - - - - - - -.. cfunction:: float cvFastArctan(float y, float x) - - Calculates the angle of a 2D vector. - - - - - - - :param x: x-coordinate of 2D vector - - - :param y: y-coordinate of 2D vector - - - -The function calculates the full-range angle of an input 2D vector. The angle is -measured in degrees and varies from 0 degrees to 360 degrees. The accuracy is about 0.1 degrees. - - -.. index:: Flip - -.. _Flip: - -Flip ----- - - - - - - -.. cfunction:: void cvFlip(const CvArr* src, CvArr* dst=NULL, int flipMode=0) - - Flip a 2D array around vertical, horizontal or both axes. - - - - - - - :param src: Source array - - - :param dst: Destination array. - If :math:`\texttt{dst} = \texttt{NULL}` the flipping is done in place. - - - :param flipMode: Specifies how to flip the array: - 0 means flipping around the x-axis, positive (e.g., 1) means flipping around y-axis, and negative (e.g., -1) means flipping around both axes. See also the discussion below for the formulas: - - - -The function flips the array in one of three different ways (row and column indices are 0-based): - - - -.. math:: - - dst(i,j) = \forkthree{\texttt{src}(rows(\texttt{src})-i-1,j)}{if $\texttt{flipMode} = 0$}{\texttt{src}(i,cols(\texttt{src})-j-1)}{if $\texttt{flipMode} > 0$}{\texttt{src}(rows(\texttt{src})-i-1,cols(\texttt{src})-j-1)}{if $\texttt{flipMode} < 0$} - - -The example scenarios of function use are: - - - - -* - vertical flipping of the image (flipMode = 0) to switch between top-left and bottom-left image origin, which is a typical operation in video processing under Win32 systems. - - - -* - horizontal flipping of the image with subsequent horizontal shift and absolute difference calculation to check for a vertical-axis symmetry (flipMode - :math:`>` - 0) - - - -* - simultaneous horizontal and vertical flipping of the image with subsequent shift and absolute difference calculation to check for a central symmetry (flipMode - :math:`<` - 0) - - - -* - reversing the order of 1d point arrays (flipMode > 0) - - - -.. index:: GEMM - -.. _GEMM: - -GEMM ----- - - - - - - -.. cfunction:: void cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, const CvArr* src3, double beta, CvArr* dst, int tABC=0) - - - -.. cfunction:: \#define cvMatMulAdd(src1, src2, src3, dst ) cvGEMM(src1, src2, 1, src3, 1, dst, 0 )\#define cvMatMul(src1, src2, dst ) cvMatMulAdd(src1, src2, 0, dst ) - - Performs generalized matrix multiplication. - - - - - - - :param src1: The first source array - - - :param src2: The second source array - - - :param src3: The third source array (shift). Can be NULL, if there is no shift. - - - :param dst: The destination array - - - :param tABC: The operation flags that can be 0 or a combination of the following values - - * **CV_GEMM_A_T** transpose src1 - - * **CV_GEMM_B_T** transpose src2 - - * **CV_GEMM_C_T** transpose src3 - - - - For example, ``CV_GEMM_A_T+CV_GEMM_C_T`` corresponds to - - .. math:: - - \texttt{alpha} \, \texttt{src1} ^T \, \texttt{src2} + \texttt{beta} \, \texttt{src3} ^T - - - - - -The function performs generalized matrix multiplication: - - - -.. math:: - - \texttt{dst} = \texttt{alpha} \, op( \texttt{src1} ) \, op( \texttt{src2} ) + \texttt{beta} \, op( \texttt{src3} ) \quad \text{where $op(X)$ is $X$ or $X^T$} - - -All the matrices should have the same data type and coordinated sizes. Real or complex floating-point matrices are supported. - - -.. index:: Get?D - -.. _Get?D: - -Get?D ------ - - - - - - -.. cfunction:: CvScalar cvGet1D(const CvArr* arr, int idx0) CvScalar cvGet2D(const CvArr* arr, int idx0, int idx1) CvScalar cvGet3D(const CvArr* arr, int idx0, int idx1, int idx2) CvScalar cvGetND(const CvArr* arr, int* idx) - - Return a specific array element. - - - - - - - :param arr: Input array - - - :param idx0: The first zero-based component of the element index - - - :param idx1: The second zero-based component of the element index - - - :param idx2: The third zero-based component of the element index - - - :param idx: Array of the element indices - - - -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). - -.. index:: GetCol(s) - -.. _GetCol(s): - -GetCol(s) ---------- - - - - - - -.. cfunction:: CvMat* cvGetCol(const CvArr* arr, CvMat* submat, int col) - - Returns array column or column span. - - - - - -.. cfunction:: CvMat* cvGetCols(const CvArr* arr, CvMat* submat, int startCol, int endCol) - - - - - - - - :param arr: Input array - - - :param submat: Pointer to the resulting sub-array header - - - :param col: Zero-based index of the selected column - - - :param startCol: Zero-based index of the starting column (inclusive) of the span - - - :param endCol: Zero-based index of the ending column (exclusive) of the span - - - -The functions -``GetCol`` -and -``GetCols`` -return the header, corresponding to a specified column span of the input array. -``GetCol`` -is a shortcut for -:ref:`GetCols` -: - - - - -:: - - - - cvGetCol(arr, submat, col); // ~ cvGetCols(arr, submat, col, col + 1); - - -.. - - -.. index:: GetDiag - -.. _GetDiag: - -GetDiag -------- - - - - - - -.. cfunction:: CvMat* cvGetDiag(const CvArr* arr, CvMat* submat, int diag=0) - - Returns one of array diagonals. - - - - - - - :param arr: Input array - - - :param submat: Pointer to the resulting sub-array header - - - :param diag: Array diagonal. Zero corresponds to the main diagonal, -1 corresponds to the diagonal above the main , 1 corresponds to the diagonal below the main, and so forth. - - - -The function returns the header, corresponding to a specified diagonal of the input array. - - -cvGetDims, cvGetDimSize ------------------------ - - -Return number of array dimensions and their sizes or the size of a particular dimension. - - - -.. cfunction:: int cvGetDims(const CvArr* arr, int* sizes=NULL) - - - - - - -.. cfunction:: int cvGetDimSize(const CvArr* arr, int index) - - - - - - - - :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. - - - :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) - - - -The function -``cvGetDims`` -returns the array dimensionality and the -array of dimension sizes. In the case of -``IplImage`` -or -:ref:`CvMat` -it always -returns 2 regardless of number of image/matrix rows. The function -``cvGetDimSize`` -returns the particular dimension size (number of -elements per that dimension). For example, the following code calculates -total number of array elements in two ways: - - - - -:: - - - - // via cvGetDims() - int sizes[CV_MAX_DIM]; - int i, total = 1; - int dims = cvGetDims(arr, size); - for(i = 0; i < dims; i++ ) - total *= sizes[i]; - - // via cvGetDims() and cvGetDimSize() - int i, total = 1; - int dims = cvGetDims(arr); - for(i = 0; i < dims; i++ ) - total *= cvGetDimsSize(arr, i); - - -.. - - -.. index:: GetElemType - -.. _GetElemType: - -GetElemType ------------ - - - - - - -.. cfunction:: int cvGetElemType(const CvArr* arr) - - Returns type of array elements. - - - - - - - :param arr: Input array - - - -The function returns type of the array elements -as described in -:ref:`CreateMat` -discussion: -``CV_8UC1`` -... -``CV_64FC4`` -. - - - -.. index:: GetImage - -.. _GetImage: - -GetImage --------- - - - - - - -.. cfunction:: IplImage* cvGetImage(const CvArr* arr, IplImage* imageHeader) - - Returns image header for arbitrary array. - - - - - - - :param arr: Input array - - - :param imageHeader: Pointer to ``IplImage`` structure used as a temporary buffer - - - -The function returns the image header for the input array -that can be a matrix - -:ref:`CvMat` -, or an image - -``IplImage*`` -. In -the case of an image the function simply returns the input pointer. In the -case of -:ref:`CvMat` -it initializes an -``imageHeader`` -structure -with the parameters of the input matrix. Note that if we transform -``IplImage`` -to -:ref:`CvMat` -and then transform CvMat back to -IplImage, we can get different headers if the ROI is set, and thus some -IPL functions that calculate image stride from its width and align may -fail on the resultant image. - - -.. index:: GetImageCOI - -.. _GetImageCOI: - -GetImageCOI ------------ - - - - - - -.. cfunction:: int cvGetImageCOI(const IplImage* image) - - Returns the index of the channel of interest. - - - - - - - :param image: A pointer to the image header - - - -Returns the channel of interest of in an IplImage. Returned values correspond to the -``coi`` -in -:ref:`SetImageCOI` -. - - -.. index:: GetImageROI - -.. _GetImageROI: - -GetImageROI ------------ - - - - - - -.. cfunction:: CvRect cvGetImageROI(const IplImage* image) - - Returns the image ROI. - - - - - - - :param image: A pointer to the image header - - - -If there is no ROI set, -``cvRect(0,0,image->width,image->height)`` -is returned. - - -.. index:: GetMat - -.. _GetMat: - -GetMat ------- - - - - - - -.. cfunction:: CvMat* cvGetMat(const CvArr* arr, CvMat* header, int* coi=NULL, int allowND=0) - - Returns matrix header for arbitrary array. - - - - - - - :param arr: Input array - - - :param header: Pointer to :ref:`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 (if CvMatND has two dimensions) or 1D matrix (when CvMatND has 1 dimension or more than 2 dimensions). The array must be continuous. - - - -The function returns a matrix header for the input array that can be a matrix - - -:ref:`CvMat` -, an image - -``IplImage`` -or a multi-dimensional dense array - -:ref:`CvMatND` -(latter case is allowed only if -``allowND != 0`` -) . In the case of matrix the function simply returns the input pointer. In the case of -``IplImage*`` -or -:ref:`CvMatND` -it initializes the -``header`` -structure with parameters of the current image ROI and returns the pointer to this temporary structure. Because COI is not supported by -:ref:`CvMat` -, it is returned separately. - -The function provides an easy way to handle both types of arrays - -``IplImage`` -and -:ref:`CvMat` -- using the same code. Reverse transform from -:ref:`CvMat` -to -``IplImage`` -can be done using the -:ref:`GetImage` -function. - -Input array must have underlying data allocated or attached, otherwise the function fails. - -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. It enables per-plane processing of multi-channel images with planar data layout using OpenCV functions. - - -.. index:: GetNextSparseNode - -.. _GetNextSparseNode: - -GetNextSparseNode ------------------ - - - - - - -.. cfunction:: CvSparseNode* cvGetNextSparseNode(CvSparseMatIterator* matIterator) - - Returns the next sparse matrix element - - - - - - - :param matIterator: Sparse array iterator - - - -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: - -Using -:ref:`InitSparseMatIterator` -and -:ref:`GetNextSparseNode` -to calculate sum of floating-point sparse array. - - - - -:: - - - - double sum; - int i, dims = cvGetDims(array); - CvSparseMatIterator mat_iterator; - CvSparseNode* node = cvInitSparseMatIterator(array, &mat_iterator); - - for(; node != 0; node = cvGetNextSparseNode(&mat_iterator )) - { - /* get pointer to the element indices */ - int* idx = CV_NODE_IDX(array, node); - /* get value of the element (assume that the type is CV_32FC1) */ - float val = *(float*)CV_NODE_VAL(array, node); - printf("("); - for(i = 0; i < dims; i++ ) - printf(" - printf(" - - sum += val; - } - - printf("nTotal sum = - - -.. - - -.. index:: GetOptimalDFTSize - -.. _GetOptimalDFTSize: - -GetOptimalDFTSize ------------------ - - - - - - -.. cfunction:: int cvGetOptimalDFTSize(int size0) - - Returns optimal DFT size for a given vector size. - - - - - - - :param size0: Vector size - - - -The function returns the minimum number -``N`` -that is greater than or equal to -``size0`` -, such that the DFT -of a vector of size -``N`` -can be computed fast. In the current -implementation -:math:`N=2^p \times 3^q \times 5^r` -, for some -:math:`p` -, -:math:`q` -, -:math:`r` -. - -The function returns a negative number if -``size0`` -is too large -(very close to -``INT_MAX`` -) - - - -.. index:: GetRawData - -.. _GetRawData: - -GetRawData ----------- - - - - - - -.. cfunction:: void cvGetRawData(const CvArr* arr, uchar** data, int* step=NULL, CvSize* roiSize=NULL) - - Retrieves low-level information about the array. - - - - - - - :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 roiSize: Output ROI size - - - -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. GetRawData calculates the absolute value of the elements in a single-channel, floating-point array. - - - - -:: - - - - float* data; - int step; - - CvSize size; - int x, y; - - cvGetRawData(array, (uchar**)&data, &step, &size); - step /= sizeof(data[0]); - - for(y = 0; y < size.height; y++, data += step ) - for(x = 0; x < size.width; x++ ) - data[x] = (float)fabs(data[x]); - - - -.. - - -.. index:: GetReal1D - -.. _GetReal1D: - -GetReal1D ---------- - - - - - - -.. cfunction:: double cvGetReal1D(const CvArr* arr, int idx0) - - Return a specific element of single-channel 1D array. - - - - - - - :param arr: Input array. Must have a single channel. - - - :param idx0: The first zero-based component of the element index - - - -Returns a specific element of a single-channel array. If the array has -multiple channels, a runtime error is raised. Note that -:ref:`Get` -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 return 0 if the requested node does not exist (no new node is created by the functions). - - -.. index:: GetReal2D - -.. _GetReal2D: - -GetReal2D ---------- - - - - - - -.. cfunction:: double cvGetReal2D(const CvArr* arr, int idx0, int idx1) - - Return a specific element of single-channel 2D array. - - - - - - - :param arr: Input array. Must have a single channel. - - - :param idx0: The first zero-based component of the element index - - - :param idx1: The second zero-based component of the element index - - - -Returns a specific element of a single-channel array. If the array has -multiple channels, a runtime error is raised. Note that -:ref:`Get` -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 return 0 if the requested node does not exist (no new node is created by the functions). - - -.. index:: GetReal3D - -.. _GetReal3D: - -GetReal3D ---------- - - - - - - -.. cfunction:: double cvGetReal3D(const CvArr* arr, int idx0, int idx1, int idx2) - - Return a specific element of single-channel array. - - - - - - - :param arr: Input array. Must have a single channel. - - - :param idx0: The first zero-based component of the element index - - - :param idx1: The second zero-based component of the element index - - - :param idx2: The third zero-based component of the element index - - - -Returns a specific element of a single-channel array. If the array has -multiple channels, a runtime error is raised. Note that -:ref:`Get` -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 return 0 if the requested node does not exist (no new node is created by the functions). - - -.. index:: GetRealND - -.. _GetRealND: - -GetRealND ---------- - - - - - - -.. cfunction:: double cvGetRealND(const CvArr* arr, int* idx)->float - - Return a specific element of single-channel array. - - - - - - - :param arr: Input array. Must have a single channel. - - - :param idx: Array of the element indices - - - -Returns a specific element of a single-channel array. If the array has -multiple channels, a runtime error is raised. Note that -:ref:`Get` -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 return 0 if the requested node does not exist (no new node is created by the functions). - - - -.. index:: GetRow(s) - -.. _GetRow(s): - -GetRow(s) ---------- - - - - - - -.. cfunction:: CvMat* cvGetRow(const CvArr* arr, CvMat* submat, int row) - - Returns array row or row span. - - - - - -.. cfunction:: CvMat* cvGetRows(const CvArr* arr, CvMat* submat, int startRow, int endRow, int deltaRow=1) - - - - - - - - :param arr: Input array - - - :param submat: Pointer to the resulting sub-array header - - - :param row: Zero-based index of the selected row - - - :param startRow: Zero-based index of the starting row (inclusive) of the span - - - :param endRow: Zero-based index of the ending row (exclusive) of the span - - - :param deltaRow: Index step in the row span. That is, the function extracts every ``deltaRow`` -th row from ``startRow`` and up to (but not including) ``endRow`` . - - - -The functions return the header, corresponding to a specified row/row span of the input array. Note that -``GetRow`` -is a shortcut for -:ref:`GetRows` -: - - - - -:: - - - - cvGetRow(arr, submat, row ) ~ cvGetRows(arr, submat, row, row + 1, 1); - - -.. - - -.. index:: GetSize - -.. _GetSize: - -GetSize -------- - - - - - - -.. cfunction:: CvSize cvGetSize(const CvArr* arr) - - Returns size of matrix or image ROI. - - - - - - - :param arr: array header - - - -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. - - - -.. index:: GetSubRect - -.. _GetSubRect: - -GetSubRect ----------- - - - - - - -.. cfunction:: CvMat* cvGetSubRect(const CvArr* arr, CvMat* submat, CvRect rect) - - Returns matrix header corresponding to the rectangular sub-array of input image or matrix. - - - - - - - :param arr: Input array - - - :param submat: Pointer to the resultant sub-array header - - - :param rect: Zero-based coordinates of the rectangle of interest - - - -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. - - -.. index:: InRange - -.. _InRange: - -InRange -------- - - - - - - -.. cfunction:: void cvInRange(const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst) - - Checks that array elements lie between the elements of two other arrays. - - - - - - - :param src: The first source array - - - :param lower: The inclusive lower boundary array - - - :param upper: The exclusive upper boundary array - - - :param dst: The destination array, must have 8u or 8s type - - - -The function does the range check for every element of the input array: - - - -.. math:: - - \texttt{dst} (I)= \texttt{lower} (I)_0 <= \texttt{src} (I)_0 < \texttt{upper} (I)_0 - - -For single-channel arrays, - - - -.. math:: - - \texttt{dst} (I)= \texttt{lower} (I)_0 <= \texttt{src} (I)_0 < \texttt{upper} (I)_0 \land \texttt{lower} (I)_1 <= \texttt{src} (I)_1 < \texttt{upper} (I)_1 - - -For two-channel arrays and so forth, - -dst(I) is set to 0xff (all -``1`` --bits) if src(I) is within the range and 0 otherwise. All the arrays must have the same type, except the destination, and the same size (or ROI size). - - - -.. index:: InRangeS - -.. _InRangeS: - -InRangeS --------- - - - - - - -.. cfunction:: void cvInRangeS(const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst) - - Checks that array elements lie between two scalars. - - - - - - - :param src: The first source array - - - :param lower: The inclusive lower boundary - - - :param upper: The exclusive upper boundary - - - :param dst: The destination array, must have 8u or 8s type - - - -The function does the range check for every element of the input array: - - - -.. math:: - - \texttt{dst} (I)= \texttt{lower} _0 <= \texttt{src} (I)_0 < \texttt{upper} _0 - - -For single-channel arrays, - - - -.. math:: - - \texttt{dst} (I)= \texttt{lower} _0 <= \texttt{src} (I)_0 < \texttt{upper} _0 \land \texttt{lower} _1 <= \texttt{src} (I)_1 < \texttt{upper} _1 - - -For two-channel arrays nd so forth, - -'dst(I)' is set to 0xff (all -``1`` --bits) if 'src(I)' is within the range and 0 otherwise. All the arrays must have the same size (or ROI size). - - -.. index:: IncRefData - -.. _IncRefData: - -IncRefData ----------- - - - - - - -.. cfunction:: int cvIncRefData(CvArr* arr) - - Increments array data reference counter. - - - - - - - :param arr: Array header - - - -The function increments -:ref:`CvMat` -or -:ref:`CvMatND` -data reference counter and returns the new counter value -if the reference counter pointer is not NULL, otherwise it returns zero. - - -.. index:: InitImageHeader - -.. _InitImageHeader: - -InitImageHeader ---------------- - - - - - - -.. cfunction:: IplImage* cvInitImageHeader( IplImage* image, CvSize size, int depth, int channels, int origin=0, int align=4) - - Initializes an image header that was previously allocated. - - - - - - - :param image: Image header to initialize - - - :param size: Image width and height - - - :param depth: Image depth (see :ref:`CreateImage` ) - - - :param channels: Number of channels (see :ref:`CreateImage` ) - - - :param origin: Top-left ``IPL_ORIGIN_TL`` or bottom-left ``IPL_ORIGIN_BL`` - - - :param align: Alignment for image rows, typically 4 or 8 bytes - - - -The returned -``IplImage*`` -points to the initialized header. - - -.. index:: InitMatHeader - -.. _InitMatHeader: - -InitMatHeader -------------- - - - - - - -.. cfunction:: CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, int type, void* data=NULL, int step=CV_AUTOSTEP) - - Initializes a pre-allocated matrix header. - - - - - - - :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 :ref:`CreateMat` . - - - :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. - - - -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: - - - - -:: - - - - 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) - - - -.. - - -.. index:: InitMatNDHeader - -.. _InitMatNDHeader: - -InitMatNDHeader ---------------- - - - - - - -.. cfunction:: CvMatND* cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int type, void* data=NULL) - - 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 :ref:`CreateMat` - - - :param data: Optional data pointer assigned to the matrix header - - - - -.. index:: InitSparseMatIterator - -.. _InitSparseMatIterator: - -InitSparseMatIterator ---------------------- - - - - - - -.. cfunction:: CvSparseNode* cvInitSparseMatIterator(const CvSparseMat* mat, CvSparseMatIterator* matIterator) - - Initializes sparse array elements iterator. - - - - - - - :param mat: Input array - - - :param matIterator: Initialized iterator - - - -The function initializes iterator of -sparse array elements and returns pointer to the first element, or NULL -if the array is empty. - - -.. index:: InvSqrt - -.. _InvSqrt: - -InvSqrt -------- - - - - - - -.. cfunction:: float cvInvSqrt(float value) - - Calculates the inverse square root. - - - - - - - :param value: The input floating-point value - - - -The function calculates the inverse square root of the argument, and normally it is faster than -``1./sqrt(value)`` -. If the argument is zero or negative, the result is not determined. Special values ( -:math:`\pm \infty` -, NaN) are not handled. - - -.. index:: Inv - -.. _Inv: - -Inv ---- - - - - -:ref:`Invert` - -.. index:: - -.. _: - - - - - - - - - -.. cfunction:: double cvInvert(const CvArr* src, CvArr* dst, int method=CV_LU) - - Finds the inverse or pseudo-inverse of a matrix. - - - - - - - :param src: The source matrix - - - :param dst: The destination matrix - - - :param method: Inversion method - - - * **CV_LU** Gaussian elimination with optimal pivot element chosen - - - * **CV_SVD** Singular value decomposition (SVD) method - - - * **CV_SVD_SYM** SVD method for a symmetric positively-defined matrix - - - - - -The function inverts matrix -``src1`` -and stores the result in -``src2`` -. - -In the case of -``LU`` -method, the function returns the -``src1`` -determinant (src1 must be square). If it is 0, the matrix is not inverted and -``src2`` -is filled with zeros. - -In the case of -``SVD`` -methods, the function returns the inversed condition of -``src1`` -(ratio of the smallest singular value to the largest singular value) and 0 if -``src1`` -is all zeros. The SVD methods calculate a pseudo-inverse matrix if -``src1`` -is singular. - - - -.. index:: IsInf - -.. _IsInf: - -IsInf ------ - - - - - - -.. cfunction:: int cvIsInf(double value) - - Determines if the argument is Infinity. - - - - - - - :param value: The input floating-point value - - - -The function returns 1 if the argument is -:math:`\pm \infty` -(as defined by IEEE754 standard), 0 otherwise. - - -.. index:: IsNaN - -.. _IsNaN: - -IsNaN ------ - - - - - - -.. cfunction:: int cvIsNaN(double value) - - 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. - - - -.. index:: LUT - -.. _LUT: - -LUT ---- - - - - - - -.. cfunction:: void cvLUT(const CvArr* src, CvArr* dst, const CvArr* lut) - - Performs a look-up table transform of an array. - - - - - - - :param src: Source array of 8-bit elements - - - :param dst: Destination array of a given depth and of the same number of channels as the source array - - - :param lut: Look-up table of 256 elements; should have the same depth as the destination array. In the case of multi-channel source and destination arrays, 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 the source/destination array. - - - -The function fills the destination array with values from the look-up table. Indices of the entries are taken from the source array. That is, the function processes each element of -``src`` -as follows: - - - -.. math:: - - \texttt{dst} _i \leftarrow \texttt{lut} _{ \texttt{src} _i + d} - - -where - - - -.. math:: - - d = \fork{0}{if \texttt{src} has depth \texttt{CV\_8U}}{128}{if \texttt{src} has depth \texttt{CV\_8S}} - - - -.. index:: Log - -.. _Log: - -Log ---- - - - - - - -.. cfunction:: void cvLog(const CvArr* src, CvArr* dst) - - Calculates the natural logarithm of every array element's absolute value. - - - - - - - :param src: The source array - - - :param dst: The destination array, it should have ``double`` type or the same type as the source - - - -The function calculates the natural logarithm of the absolute value of every element of the input array: - - - -.. math:: - - \texttt{dst} [I] = \fork{\log{|\texttt{src}(I)}}{if $\texttt{src}[I] \ne 0$ }{\texttt{C}}{otherwise} - - -Where -``C`` -is a large negative number (about -700 in the current implementation). - - -.. index:: Mahalanobis - -.. _Mahalanobis: - -Mahalanobis ------------ - - - - - - -.. cfunction:: double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat) - - Calculates the Mahalanobis distance between two vectors. - - - - - - - :param vec1: The first 1D source vector - - - :param vec2: The second 1D source vector - - - :param mat: The inverse covariance matrix - - - -The function calculates and returns the weighted distance between two vectors: - - - -.. math:: - - 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)})} } - - -The covariance matrix may be calculated using the -:ref:`CalcCovarMatrix` -function and further inverted using the -:ref:`Invert` -function (CV -_ -SVD method is the prefered one because the matrix might be singular). - - - -.. index:: Mat - -.. _Mat: - -Mat ---- - - - - - - -.. cfunction:: CvMat cvMat( int rows, int cols, int type, void* data=NULL) - - Initializes matrix header (lightweight variant). - - - - - - - :param rows: Number of rows in the matrix - - - :param cols: Number of columns in the matrix - - - :param type: Type of the matrix elements - see :ref:`CreateMat` - - - :param data: Optional data pointer assigned to the matrix header - - - -Initializes a matrix header and assigns data to it. The matrix is filled -*row* --wise (the first -``cols`` -elements of data form the first row of the matrix, etc.) - -This function is a fast inline substitution for -:ref:`InitMatHeader` -. Namely, it is equivalent to: - - - - -:: - - - - CvMat mat; - cvInitMatHeader(&mat, rows, cols, type, data, CV_AUTOSTEP); - - -.. - - -.. index:: Max - -.. _Max: - -Max ---- - - - - - - -.. cfunction:: void cvMax(const CvArr* src1, const CvArr* src2, CvArr* dst) - - Finds per-element maximum of two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second source array - - - :param dst: The destination array - - - -The function calculates per-element maximum of two arrays: - - - -.. math:: - - \texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I)) - - -All the arrays must have a single channel, the same data type and the same size (or ROI size). - - - -.. index:: MaxS - -.. _MaxS: - -MaxS ----- - - - - - - -.. cfunction:: void cvMaxS(const CvArr* src, double value, CvArr* dst) - - Finds per-element maximum of array and scalar. - - - - - - - :param src: The first source array - - - :param value: The scalar value - - - :param dst: The destination array - - - -The function calculates per-element maximum of array and scalar: - - - -.. math:: - - \texttt{dst} (I)= \max ( \texttt{src} (I), \texttt{value} ) - - -All the arrays must have a single channel, the same data type and the same size (or ROI size). - - - -.. index:: Merge - -.. _Merge: - -Merge ------ - - - - - - -.. cfunction:: void cvMerge(const CvArr* src0, const CvArr* src1, const CvArr* src2, const CvArr* src3, CvArr* dst) - - Composes a multi-channel array from several single-channel arrays or inserts a single channel into the array. - - - - - - -:: - - - - #define cvCvtPlaneToPix cvMerge - - -.. - - - - - :param src0: Input channel 0 - - - :param src1: Input channel 1 - - - :param src2: Input channel 2 - - - :param src3: Input channel 3 - - - :param dst: Destination array - - - -The function is the opposite to -:ref:`Split` -. If the destination array has N channels then if the first N input channels are not NULL, they all are copied to the destination array; if only a single source channel of the first N is not NULL, this particular channel is copied into the destination array; otherwise an error is raised. The rest of the source channels (beyond the first N) must always be NULL. For IplImage -:ref:`Copy` -with COI set can be also used to insert a single channel into the image. - - -.. index:: Min - -.. _Min: - -Min ---- - - - - - - -.. cfunction:: void cvMin(const CvArr* src1, const CvArr* src2, CvArr* dst) - - Finds per-element minimum of two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second source array - - - :param dst: The destination array - - - -The function calculates per-element minimum of two arrays: - - - -.. math:: - - \texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I)) - - -All the arrays must have a single channel, the same data type and the same size (or ROI size). - - - -.. index:: MinMaxLoc - -.. _MinMaxLoc: - -MinMaxLoc ---------- - - - - - - -.. cfunction:: void cvMinMaxLoc(const CvArr* arr, double* minVal, double* maxVal, CvPoint* minLoc=NULL, CvPoint* maxLoc=NULL, const CvArr* mask=NULL) - - Finds global minimum and maximum in array or subarray. - - - - - - - :param arr: The source array, single-channel or multi-channel with COI set - - - :param minVal: Pointer to returned minimum value - - - :param maxVal: Pointer to returned maximum value - - - :param minLoc: Pointer to returned minimum location - - - :param maxLoc: Pointer to returned maximum location - - - :param mask: The optional mask used to select a subarray - - - -The function finds minimum and maximum element values -and their positions. The extremums are searched across the whole array, -selected -``ROI`` -(in the case of -``IplImage`` -) or, if -``mask`` -is not -``NULL`` -, in the specified array region. If the array has -more than one channel, it must be -``IplImage`` -with -``COI`` -set. In the case of multi-dimensional arrays, -``minLoc->x`` -and -``maxLoc->x`` -will contain raw (linear) positions of the extremums. - - -.. index:: MinS - -.. _MinS: - -MinS ----- - - - - - - -.. cfunction:: void cvMinS(const CvArr* src, double value, CvArr* dst) - - Finds per-element minimum of an array and a scalar. - - - - - - - :param src: The first source array - - - :param value: The scalar value - - - :param dst: The destination array - - - -The function calculates minimum of an array and a scalar: - - - -.. math:: - - \texttt{dst} (I)= \min ( \texttt{src} (I), \texttt{value} ) - - -All the arrays must have a single channel, the same data type and the same size (or ROI size). - - - -Mirror ------- - - -Synonym for -:ref:`Flip` -. - - -.. index:: MixChannels - -.. _MixChannels: - -MixChannels ------------ - - - - - - -.. cfunction:: void cvMixChannels(const CvArr** src, int srcCount, CvArr** dst, int dstCount, const int* fromTo, int pairCount) - - Copies several channels from input arrays to certain channels of output arrays - - - - - - - :param src: Input arrays - - - :param srcCount: The number of input arrays. - - - :param dst: Destination arrays - - - :param dstCount: The number of output arrays. - - - :param fromTo: The array of pairs of indices of the planes - copied. ``fromTo[k*2]`` is the 0-based index of the input channel in ``src`` and ``fromTo[k*2+1]`` is the index of the output channel in ``dst`` . - Here the continuous channel numbering is used, that is, the first input image channels are indexed - from ``0`` to ``channels(src[0])-1`` , the second input image channels are indexed from ``channels(src[0])`` to ``channels(src[0]) + channels(src[1])-1`` etc., and 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. - - - -The function is a generalized form of -:ref:`cvSplit` -and -:ref:`Merge` -and some forms of -:ref:`CvtColor` -. It can be used to change the order of the -planes, add/remove alpha channel, extract or insert a single plane or -multiple planes etc. - -As an example, this code splits a 4-channel RGBA image into a 3-channel -BGR (i.e. with R and B swapped) and separate alpha channel image: - - - - -:: - - - - CvMat* rgba = cvCreateMat(100, 100, CV_8UC4); - CvMat* bgr = cvCreateMat(rgba->rows, rgba->cols, CV_8UC3); - CvMat* alpha = cvCreateMat(rgba->rows, rgba->cols, CV_8UC1); - cvSet(rgba, cvScalar(1,2,3,4)); - - CvArr* out[] = { bgr, alpha }; - int from_to[] = { 0,2, 1,1, 2,0, 3,3 }; - cvMixChannels(&bgra, 1, out, 2, from_to, 4); - - -.. - - -MulAddS -------- - - -Synonym for -:ref:`ScaleAdd` -. - - -.. index:: Mul - -.. _Mul: - -Mul ---- - - - - - - -.. cfunction:: void cvMul(const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1) - - Calculates the per-element product of two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second source array - - - :param dst: The destination array - - - :param scale: Optional scale factor - - - -The function calculates the per-element product of two arrays: - - - -.. math:: - - \texttt{dst} (I)= \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I) - - -All the arrays must have the same type and the same size (or ROI size). -For types that have limited range this operation is saturating. - - -.. index:: MulSpectrums - -.. _MulSpectrums: - -MulSpectrums ------------- - - - - - - -.. cfunction:: void cvMulSpectrums( const CvArr* src1, const CvArr* src2, CvArr* dst, int flags) - - Performs per-element multiplication of two Fourier spectrums. - - - - - - - :param src1: The first source array - - - :param src2: The second source array - - - :param dst: The destination array of the same type and the same size as the source arrays - - - :param flags: A combination of the following values; - - * **CV_DXT_ROWS** treats each row of the arrays as a separate spectrum (see :ref:`DFT` parameters description). - - * **CV_DXT_MUL_CONJ** conjugate the second source array before the multiplication. - - - - - -The function performs 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 -:ref:`DFT` -, may be used to calculate convolution of two arrays rapidly. - - - -.. index:: MulTransposed - -.. _MulTransposed: - -MulTransposed -------------- - - - - - - -.. cfunction:: void cvMulTransposed(const CvArr* src, CvArr* dst, int order, const CvArr* delta=NULL, double scale=1.0) - - Calculates the product of an array and a transposed array. - - - - - - - :param src: The source matrix - - - :param dst: The destination matrix. Must be ``CV_32F`` or ``CV_64F`` . - - - :param order: Order of multipliers - - - :param delta: An optional array, subtracted from ``src`` before multiplication - - - :param scale: An optional scaling - - - -The function calculates the product of src and its transposition: - - - -.. math:: - - \texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} ) ( \texttt{src} - \texttt{delta} )^T - - -if -:math:`\texttt{order}=0` -, and - - - -.. math:: - - \texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} )^T ( \texttt{src} - \texttt{delta} ) - - -otherwise. - - -.. index:: Norm - -.. _Norm: - -Norm ----- - - - - - - -.. cfunction:: double cvNorm(const CvArr* arr1, const CvArr* arr2=NULL, int normType=CV_L2, const CvArr* mask=NULL) - - Calculates absolute array norm, absolute difference norm, or relative difference norm. - - - - - - - :param arr1: The first source image - - - :param arr2: The second source image. If it is NULL, the absolute norm of ``arr1`` is calculated, otherwise the absolute or relative norm of ``arr1`` - ``arr2`` is calculated. - - - :param normType: Type of norm, see the discussion - - - :param mask: The optional operation mask - - - -The function calculates the absolute norm of -``arr1`` -if -``arr2`` -is NULL: - - -.. math:: - - norm = \forkthree{||\texttt{arr1}||_C = \max_I |\texttt{arr1}(I)|}{if $\texttt{normType} = \texttt{CV\_C}$}{||\texttt{arr1}||_{L1} = \sum_I |\texttt{arr1}(I)|}{if $\texttt{normType} = \texttt{CV\_L1}$}{||\texttt{arr1}||_{L2} = \sqrt{\sum_I \texttt{arr1}(I)^2}}{if $\texttt{normType} = \texttt{CV\_L2}$} - - -or the absolute difference norm if -``arr2`` -is not NULL: - - -.. math:: - - norm = \forkthree{||\texttt{arr1}-\texttt{arr2}||_C = \max_I |\texttt{arr1}(I) - \texttt{arr2}(I)|}{if $\texttt{normType} = \texttt{CV\_C}$}{||\texttt{arr1}-\texttt{arr2}||_{L1} = \sum_I |\texttt{arr1}(I) - \texttt{arr2}(I)|}{if $\texttt{normType} = \texttt{CV\_L1}$}{||\texttt{arr1}-\texttt{arr2}||_{L2} = \sqrt{\sum_I (\texttt{arr1}(I) - \texttt{arr2}(I))^2}}{if $\texttt{normType} = \texttt{CV\_L2}$} - - -or the relative difference norm if -``arr2`` -is not NULL and -``(normType & CV_RELATIVE) != 0`` -: - - - -.. math:: - - norm = \forkthree{\frac{||\texttt{arr1}-\texttt{arr2}||_C }{||\texttt{arr2}||_C }}{if $\texttt{normType} = \texttt{CV\_RELATIVE\_C}$}{\frac{||\texttt{arr1}-\texttt{arr2}||_{L1} }{||\texttt{arr2}||_{L1}}}{if $\texttt{normType} = \texttt{CV\_RELATIVE\_L1}$}{\frac{||\texttt{arr1}-\texttt{arr2}||_{L2} }{||\texttt{arr2}||_{L2}}}{if $\texttt{normType} = \texttt{CV\_RELATIVE\_L2}$} - - -The function returns the calculated norm. A multiple-channel array is treated as a single-channel, that is, the results for all channels are combined. - - -.. index:: Not - -.. _Not: - -Not ---- - - - - - - -.. cfunction:: void cvNot(const CvArr* src, CvArr* dst) - - Performs per-element bit-wise inversion of array elements. - - - - - - - :param src: The source array - - - :param dst: The destination array - - - -The function Not inverses every bit of every array element: - - - - -:: - - - - dst(I)=~src(I) - - -.. - - -.. index:: Or - -.. _Or: - -Or --- - - - - - - -.. cfunction:: void cvOr(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) - - Calculates per-element bit-wise disjunction of two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second 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 - - - -The function calculates per-element bit-wise disjunction of two arrays: - - - - -:: - - - - dst(I)=src1(I)|src2(I) - - -.. - -In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - -.. index:: OrS - -.. _OrS: - -OrS ---- - - - - - - -.. cfunction:: void cvOrS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) - - Calculates a per-element bit-wise disjunction of an array and a scalar. - - - - - - - :param src: The source array - - - :param value: Scalar to use in the operation - - - :param dst: The destination array - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - - -The function OrS calculates per-element bit-wise disjunction of an array and a scalar: - - - - -:: - - - - dst(I)=src(I)|value if mask(I)!=0 - - -.. - -Prior to the actual operation, the scalar is converted to the same type as that of the array(s). In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - - -.. index:: PerspectiveTransform - -.. _PerspectiveTransform: - -PerspectiveTransform --------------------- - - - - - - -.. cfunction:: void cvPerspectiveTransform(const CvArr* src, CvArr* dst, const CvMat* mat) - - Performs perspective matrix transformation of a vector array. - - - - - - - :param src: The source three-channel floating-point array - - - :param dst: The destination three-channel floating-point array - - - :param mat: :math:`3\times 3` or :math:`4 \times 4` transformation matrix - - - -The function transforms every element of -``src`` -(by treating it as 2D or 3D vector) in the following way: - - - -.. math:: - - (x, y, z) \rightarrow (x'/w, y'/w, z'/w) - - -where - - - -.. math:: - - (x', y', z', w') = \texttt{mat} \cdot \begin{bmatrix} x & y & z & 1 \end{bmatrix} - - -and - - -.. math:: - - w = \fork{w'}{if $w' \ne 0$}{\infty}{otherwise} - - - -.. index:: PolarToCart - -.. _PolarToCart: - -PolarToCart ------------ - - - - - - -.. cfunction:: void cvPolarToCart( const CvArr* magnitude, const CvArr* angle, CvArr* x, CvArr* y, int angleInDegrees=0) - - Calculates Cartesian coordinates of 2d vectors represented in polar form. - - - - - - - :param magnitude: The array of magnitudes. If it is NULL, the magnitudes are assumed to be all 1's. - - - :param angle: The array of angles, whether in radians or degrees - - - :param x: The destination array of x-coordinates, may be set to NULL if it is not needed - - - :param y: The destination array of y-coordinates, mau be set to NULL if it is not needed - - - :param angleInDegrees: The flag indicating whether the angles are measured in radians, which is default mode, or in degrees - - - -The function calculates either the x-coodinate, y-coordinate or both of every vector -``magnitude(I)*exp(angle(I)*j), j=sqrt(-1)`` -: - - - - -:: - - - - x(I)=magnitude(I)*cos(angle(I)), - y(I)=magnitude(I)*sin(angle(I)) - - -.. - - -.. index:: Pow - -.. _Pow: - -Pow ---- - - - - - - -.. cfunction:: void cvPow( const CvArr* src, CvArr* dst, double power) - - Raises every array element to a power. - - - - - - - :param src: The source array - - - :param dst: The destination array, should be the same type as the source - - - :param power: The exponent of power - - - -The function raises every element of the input array to -``p`` -: - - - -.. math:: - - \texttt{dst} [I] = \fork{\texttt{src}(I)^p}{if \texttt{p} is integer}{|\texttt{src}(I)^p|}{otherwise} - - -That is, 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, as the following example, computing the cube root of array elements, shows: - - - - -:: - - - - CvSize size = cvGetSize(src); - CvMat* mask = cvCreateMat(size.height, size.width, CV_8UC1); - cvCmpS(src, 0, mask, CV_CMP_LT); /* find negative elements */ - cvPow(src, dst, 1./3); - cvSubRS(dst, cvScalarAll(0), dst, mask); /* negate the results of negative inputs */ - cvReleaseMat(&mask); - - -.. - -For some values of -``power`` -, such as integer values, 0.5, and -0.5, specialized faster algorithms are used. - - -.. index:: Ptr?D - -.. _Ptr?D: - -Ptr?D ------ - - - - - - -.. cfunction:: uchar* cvPtr1D(const CvArr* arr, int idx0, int* type=NULL) - - - -.. cfunction:: uchar* cvPtr2D(const CvArr* arr, int idx0, int idx1, int* type=NULL) - - - -.. cfunction:: uchar* cvPtr3D(const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL) - - - -.. cfunction:: uchar* cvPtrND(const CvArr* arr, int* idx, int* type=NULL, int createNode=1, unsigned* precalcHashval=NULL) - - Return pointer to a particular array element. - - - - - - - :param arr: Input array - - - :param idx0: The first zero-based component of the element index - - - :param idx1: The second zero-based component of the element index - - - :param idx2: The third zero-based component of the element index - - - :param idx: Array of the element indices - - - :param type: Optional output parameter: type of matrix elements - - - :param createNode: 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 precalcHashval: 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) - - - -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 ( -:ref:`Get` -, -:ref:`GetReal` -, -:ref:`Set` -, -:ref:`SetReal` -) raise an error in case if the element index is out of range. - - -.. index:: RNG - -.. _RNG: - -RNG ---- - - - - - - -.. cfunction:: CvRNG cvRNG(int64 seed=-1) - - Initializes a random number generator state. - - - - - - - :param seed: 64-bit value used to initiate a random sequence - - - -The function initializes a random number generator -and returns the state. The pointer to the state can be then passed to the -:ref:`RandInt` -, -:ref:`RandReal` -and -:ref:`RandArr` -functions. In the -current implementation a multiply-with-carry generator is used. - - -.. index:: RandArr - -.. _RandArr: - -RandArr -------- - - - - - - -.. cfunction:: void cvRandArr( CvRNG* rng, CvArr* arr, int distType, CvScalar param1, CvScalar param2) - - Fills an array with random numbers and updates the RNG state. - - - - - - - :param rng: RNG state initialized by :ref:`RNG` - - - :param arr: The destination array - - - :param distType: 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. - - - -The function fills the destination array with uniformly -or normally distributed random numbers. - -In the example below, the function -is used to add a few normally distributed floating-point numbers to -random locations within a 2d array. - - - - -:: - - - - /* let noisy_screen be the floating-point 2d array that is to be "crapped" */ - CvRNG rng_state = cvRNG(0xffffffff); - int i, pointCount = 1000; - /* allocate the array of coordinates of points */ - CvMat* locations = cvCreateMat(pointCount, 1, CV_32SC2); - /* arr of random point values */ - CvMat* values = cvCreateMat(pointCount, 1, CV_32FC1); - CvSize size = cvGetSize(noisy_screen); - - /* initialize the locations */ - cvRandArr(&rng_state, locations, CV_RAND_UNI, cvScalar(0,0,0,0), - cvScalar(size.width,size.height,0,0)); - - /* generate values */ - cvRandArr(&rng_state, values, CV_RAND_NORMAL, - cvRealScalar(100), // average intensity - cvRealScalar(30) // deviation of the intensity - ); - - /* set the points */ - for(i = 0; i < pointCount; i++ ) - { - CvPoint pt = *(CvPoint*)cvPtr1D(locations, i, 0); - float value = *(float*)cvPtr1D(values, i, 0); - *((float*)cvPtr2D(noisy_screen, pt.y, pt.x, 0 )) += value; - } - - /* not to forget to release the temporary arrays */ - cvReleaseMat(&locations); - cvReleaseMat(&values); - - /* RNG state does not need to be deallocated */ - - -.. - - -.. index:: RandInt - -.. _RandInt: - -RandInt -------- - - - - - - -.. cfunction:: unsigned cvRandInt(CvRNG* rng) - - Returns a 32-bit unsigned integer and updates RNG. - - - - - - - :param rng: RNG state initialized by ``RandInit`` and, optionally, customized by ``RandSetRange`` (though, the latter function does not affect the discussed function outcome) - - - -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, but it always generates a 32-bit number -whereas rand() returns a number in between 0 and -``RAND_MAX`` -which is -:math:`2^{16}` -or -:math:`2^{32}` -, depending on the platform. - -The function is useful for generating scalar random numbers, such as -points, patch sizes, table indices, etc., where integer numbers of a certain -range can be generated using a modulo operation and floating-point numbers -can be generated by scaling from 0 to 1 or any other specific range. - -Here is the example from the previous function discussion rewritten using -:ref:`RandInt` -: - - - - -:: - - - - /* the input and the task is the same as in the previous sample. */ - CvRNG rnggstate = cvRNG(0xffffffff); - int i, pointCount = 1000; - /* ... - no arrays are allocated here */ - CvSize size = cvGetSize(noisygscreen); - /* make a buffer for normally distributed numbers to reduce call overhead */ - #define bufferSize 16 - float normalValueBuffer[bufferSize]; - CvMat normalValueMat = cvMat(bufferSize, 1, CVg32F, normalValueBuffer); - int valuesLeft = 0; - - for(i = 0; i < pointCount; i++ ) - { - CvPoint pt; - /* generate random point */ - pt.x = cvRandInt(&rnggstate ) - pt.y = cvRandInt(&rnggstate ) - - if(valuesLeft <= 0 ) - { - /* fulfill the buffer with normally distributed numbers - if the buffer is empty */ - cvRandArr(&rnggstate, &normalValueMat, CV_RAND_NORMAL, - cvRealScalar(100), cvRealScalar(30)); - valuesLeft = bufferSize; - } - *((float*)cvPtr2D(noisygscreen, pt.y, pt.x, 0 ) = - normalValueBuffer[--valuesLeft]; - } - - /* there is no need to deallocate normalValueMat because we have - both the matrix header and the data on stack. It is a common and efficient - practice of working with small, fixed-size matrices */ - - -.. - - -.. index:: RandReal - -.. _RandReal: - -RandReal --------- - - - - - - -.. cfunction:: double cvRandReal(CvRNG* rng) - - Returns a floating-point random number and updates RNG. - - - - - - - :param rng: RNG state initialized by :ref:`RNG` - - - -The function returns a uniformly-distributed random floating-point number between 0 and 1 (1 is not included). - - -.. index:: Reduce - -.. _Reduce: - -Reduce ------- - - - - - - -.. cfunction:: void cvReduce(const CvArr* src, CvArr* dst, int dim = -1, int op=CV_REDUCE_SUM) - - Reduces a matrix to a vector. - - - - - - - :param src: The input matrix. - - - :param dst: The output single-row/single-column vector that accumulates somehow all the matrix rows/columns. - - - :param dim: The 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 and -1 means that the dimension is chosen automatically by analysing the dst size. - - - :param op: The reduction operation. It can take of the following values: - - * **CV_REDUCE_SUM** The output is the sum of all of the matrix's rows/columns. - - * **CV_REDUCE_AVG** The output is the mean vector of all of the matrix's rows/columns. - - * **CV_REDUCE_MAX** The output is the maximum (column/row-wise) of all of the matrix's rows/columns. - - * **CV_REDUCE_MIN** The output is the minimum (column/row-wise) of all of the matrix's rows/columns. - - - - - -The function reduces 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 an raster image. In the case of -``CV_REDUCE_SUM`` -and -``CV_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. - - -.. index:: ReleaseData - -.. _ReleaseData: - -ReleaseData ------------ - - - - - - -.. cfunction:: void cvReleaseData(CvArr* arr) - - Releases array data. - - - - - - - :param arr: Array header - - - -The function releases the array data. In the case of -:ref:`CvMat` -or -:ref:`CvMatND` -it simply calls cvDecRefData(), that is the function can not deallocate external data. See also the note to -:ref:`CreateData` -. - - -.. index:: ReleaseImage - -.. _ReleaseImage: - -ReleaseImage ------------- - - - - - - -.. cfunction:: void cvReleaseImage(IplImage** image) - - Deallocates the image header and the image data. - - - - - - - :param image: Double pointer to the image header - - - -This call is a shortened form of - - - - -:: - - - - if(*image ) - { - cvReleaseData(*image); - cvReleaseImageHeader(image); - } - - -.. - - -.. index:: ReleaseImageHeader - -.. _ReleaseImageHeader: - -ReleaseImageHeader ------------------- - - - - - - -.. cfunction:: void cvReleaseImageHeader(IplImage** image) - - Deallocates an image header. - - - - - - - :param image: Double pointer to the image header - - - -This call is an analogue of - - - -:: - - - - if(image ) - { - iplDeallocate(*image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI); - *image = 0; - } - - -.. - -but it does not use IPL functions by default (see the -``CV_TURN_ON_IPL_COMPATIBILITY`` -macro). - - - -.. index:: ReleaseMat - -.. _ReleaseMat: - -ReleaseMat ----------- - - - - - - -.. cfunction:: void cvReleaseMat(CvMat** mat) - - Deallocates a matrix. - - - - - - - :param mat: Double pointer to the 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. - - - - -:: - - - - if(*mat ) - cvDecRefData(*mat); - cvFree((void**)mat); - - -.. - - -.. index:: ReleaseMatND - -.. _ReleaseMatND: - -ReleaseMatND ------------- - - - - - - -.. cfunction:: void cvReleaseMatND(CvMatND** mat) - - Deallocates a multi-dimensional array. - - - - - - - :param mat: Double pointer to the 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. - - - - -:: - - - - if(*mat ) - cvDecRefData(*mat); - cvFree((void**)mat); - - -.. - - -.. index:: ReleaseSparseMat - -.. _ReleaseSparseMat: - -ReleaseSparseMat ----------------- - - - - - - -.. cfunction:: void cvReleaseSparseMat(CvSparseMat** mat) - - Deallocates sparse array. - - - - - - - :param mat: Double pointer to the array - - - -The function releases the sparse array and clears the array pointer upon exit. - - -.. index:: Repeat - -.. _Repeat: - -Repeat ------- - - - - - - -.. cfunction:: void cvRepeat(const CvArr* src, CvArr* dst) - - Fill the destination array with repeated copies of the source array. - - - - - - - :param src: Source array, image or matrix - - - :param dst: Destination array, image or matrix - - - -The function fills the destination array with repeated copies of the source array: - - - - -:: - - - - dst(i,j)=src(i mod rows(src), j mod cols(src)) - - -.. - -So the destination array may be as larger as well as smaller than the source array. - - -.. index:: ResetImageROI - -.. _ResetImageROI: - -ResetImageROI -------------- - - - - - - -.. cfunction:: void cvResetImageROI(IplImage* image) - - Resets the image ROI to include the entire image and releases the ROI structure. - - - - - - - :param image: A pointer to the image header - - - -This produces a similar result to the following -, but in addition it releases the ROI structure. - - - - -:: - - - - cvSetImageROI(image, cvRect(0, 0, image->width, image->height )); - cvSetImageCOI(image, 0); - - -.. - - -.. index:: Reshape - -.. _Reshape: - -Reshape -------- - - - - - - -.. cfunction:: CvMat* cvReshape(const CvArr* arr, CvMat* header, int newCn, int newRows=0) - - Changes shape of matrix/image without copying data. - - - - - - - :param arr: Input array - - - :param header: Output header to be filled - - - :param newCn: New number of channels. 'newCn = 0' means that the number of channels remains unchanged. - - - :param newRows: New number of rows. 'newRows = 0' means that the number of rows remains unchanged unless it needs to be changed according to ``newCn`` value. - - - -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: - - - - -:: - - - - 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); - - -.. - -And the next example converts a 3x3 matrix to a single 1x9 vector: - - - - -:: - - - - CvMat* mat = cvCreateMat(3, 3, CV_32F); - CvMat row_header, *row; - row = cvReshape(mat, &row_header, 0, 1); - - -.. - - -.. index:: ReshapeMatND - -.. _ReshapeMatND: - -ReshapeMatND ------------- - - - - - - -.. cfunction:: CvArr* cvReshapeMatND(const CvArr* arr, int sizeofHeader, CvArr* header, int newCn, int newDims, int* newSizes) - - Changes the shape of a multi-dimensional array without copying the data. - - - - - - -:: - - - - #define cvReshapeND(arr, header, newCn, newDims, newSizes ) \ - cvReshapeMatND((arr), sizeof(*(header)), (header), \ - (newCn), (newDims), (newSizes)) - - -.. - - - - - :param arr: Input array - - - :param sizeofHeader: Size of output header to distinguish between IplImage, CvMat and CvMatND output headers - - - :param header: Output header to be filled - - - :param newCn: New number of channels. :math:`\texttt{newCn} = 0` means that the number of channels remains unchanged. - - - :param newDims: New number of dimensions. :math:`\texttt{newDims} = 0` means that the number of dimensions remains the same. - - - :param newSizes: Array of new dimension sizes. Only :math:`\texttt{newDims}-1` values are used, because the total number of elements must remain the same. - Thus, if :math:`\texttt{newDims} = 1` , ``newSizes`` array is not used. - - - -The function is an advanced version of -:ref:`Reshape` -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 -:ref:`Reshape` -description rewritten using -:ref:`ReshapeMatND` -: - - - - -:: - - - - - IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); - IplImage gray_img_hdr, *gray_img; - gray_img = (IplImage*)cvReshapeND(color_img, &gray_img_hdr, 1, 0, 0); - - ... - - /* second example is modified to convert 2x2x2 array to 8x1 vector */ - int size[] = { 2, 2, 2 }; - CvMatND* mat = cvCreateMatND(3, size, CV_32F); - CvMat row_header, *row; - row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0); - - - -.. - - -.. index:: cvRound, cvFloor, cvCeil - -.. _cvRound, cvFloor, cvCeil: - -cvRound, cvFloor, cvCeil ------------------------- - - - - - - -.. cfunction:: int cvRound(double value) int cvFloor(double value) int cvCeil(double value) - - Converts a floating-point number to an integer. - - - - - - - :param value: The input floating-point value - - - -The functions convert the input floating-point number to an integer using one of the rounding -modes. -``Round`` -returns the nearest integer value to the -argument. -``Floor`` -returns the maximum integer value that is not -larger than the argument. -``Ceil`` -returns the minimum integer -value that is not smaller than the argument. On some architectures the -functions work much faster than the standard cast -operations in C. If the absolute value of the argument is greater than -:math:`2^{31}` -, the result is not determined. Special values ( -:math:`\pm \infty` -, NaN) -are not handled. - - -.. index:: ScaleAdd - -.. _ScaleAdd: - -ScaleAdd --------- - - - - - - -.. cfunction:: void cvScaleAdd(const CvArr* src1, CvScalar scale, const CvArr* src2, CvArr* dst) - - Calculates the sum of a scaled array and another array. - - - - - - - :param src1: The first source array - - - :param scale: Scale factor for the first array - - - :param src2: The second source array - - - :param dst: The destination array - - - -The function calculates the sum of a scaled array and another array: - - - -.. math:: - - \texttt{dst} (I)= \texttt{scale} \, \texttt{src1} (I) + \texttt{src2} (I) - - -All array parameters should have the same type and the same size. - - -.. index:: Set - -.. _Set: - -Set ---- - - - - - - -.. cfunction:: void cvSet(CvArr* arr, CvScalar value, const CvArr* mask=NULL) - - Sets every element of an array to a given value. - - - - - - - :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 - - - -The function copies the scalar -``value`` -to every selected element of the destination array: - - - -.. math:: - - \texttt{arr} (I)= \texttt{value} \quad \text{if} \quad \texttt{mask} (I) \ne 0 - - -If array -``arr`` -is of -``IplImage`` -type, then is ROI used, but COI must not be set. - - -.. index:: Set?D - -.. _Set?D: - -Set?D ------ - - - - - - -.. cfunction:: void cvSet1D(CvArr* arr, int idx0, CvScalar value) - - - -.. cfunction:: void cvSet2D(CvArr* arr, int idx0, int idx1, CvScalar value) - - - -.. cfunction:: void cvSet3D(CvArr* arr, int idx0, int idx1, int idx2, CvScalar value) - - - -.. cfunction:: void cvSetND(CvArr* arr, int* idx, CvScalar value) - - Change the particular array element. - - - - - - - :param arr: Input array - - - :param idx0: The first zero-based component of the element index - - - :param idx1: The second zero-based component of the element index - - - :param idx2: The third zero-based component of the element index - - - :param idx: Array of the element indices - - - :param value: The assigned value - - - -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. - - -.. index:: SetData - -.. _SetData: - -SetData -------- - - - - - - -.. cfunction:: void cvSetData(CvArr* arr, void* data, int step) - - Assigns user data to the array header. - - - - - - - :param arr: Array header - - - :param data: User data - - - :param step: Full row length in bytes - - - -The function assigns user data to the array header. Header should be initialized before using -``cvCreate*Header`` -, -``cvInit*Header`` -or -:ref:`Mat` -(in the case of matrix) function. - - -.. index:: SetIdentity - -.. _SetIdentity: - -SetIdentity ------------ - - - - - - -.. cfunction:: void cvSetIdentity(CvArr* mat, CvScalar value=cvRealScalar(1)) - - Initializes a scaled identity matrix. - - - - - - - :param mat: The matrix to initialize (not necesserily square) - - - :param value: The value to assign to the diagonal elements - - - -The function initializes a scaled identity matrix: - - - -.. math:: - - \texttt{arr} (i,j)= \fork{\texttt{value}}{ if $i=j$}{0}{otherwise} - - - -.. index:: SetImageCOI - -.. _SetImageCOI: - -SetImageCOI ------------ - - - - - - -.. cfunction:: void cvSetImageCOI( IplImage* image, int coi) - - Sets the channel of interest in an IplImage. - - - - - - - :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. - - - -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 -:ref:`Copy` -or -:ref:`Split` -) the channel to a separate -image/matrix, process it and then copy the result back (via -:ref:`Copy` -or -:ref:`Merge` -) if needed. - - -.. index:: SetImageROI - -.. _SetImageROI: - -SetImageROI ------------ - - - - - - -.. cfunction:: void cvSetImageROI( IplImage* image, CvRect rect) - - Sets an image Region Of Interest (ROI) for a given rectangle. - - - - - - - :param image: A pointer to the image header - - - :param rect: The ROI 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. - - -.. index:: SetReal?D - -.. _SetReal?D: - -SetReal?D ---------- - - - - - - -.. cfunction:: void cvSetReal1D(CvArr* arr, int idx0, double value) - - - -.. cfunction:: void cvSetReal2D(CvArr* arr, int idx0, int idx1, double value) - - - -.. cfunction:: void cvSetReal3D(CvArr* arr, int idx0, int idx1, int idx2, double value) - - - -.. cfunction:: void cvSetRealND(CvArr* arr, int* idx, double value) - - Change a specific array element. - - - - - - - :param arr: Input array - - - :param idx0: The first zero-based component of the element index - - - :param idx1: The second zero-based component of the element index - - - :param idx2: The third zero-based component of the element index - - - :param idx: Array of the element indices - - - :param value: The assigned value - - - -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 -:ref:`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. - - -.. index:: SetZero - -.. _SetZero: - -SetZero -------- - - - - - - -.. cfunction:: void cvSetZero(CvArr* arr) - - Clears the array. - - - - - - -:: - - - - #define cvZero cvSetZero - - -.. - - - - - :param arr: Array to be cleared - - - -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. - - -.. index:: Solve - -.. _Solve: - -Solve ------ - - - - - - -.. cfunction:: int cvSolve(const CvArr* src1, const CvArr* src2, CvArr* dst, int method=CV_LU) - - Solves a linear system or least-squares problem. - - - - - - - :param A: The source matrix - - - :param B: The right-hand part of the linear system - - - :param X: The output solution - - - :param method: The solution (matrix inversion) method - - - * **CV_LU** Gaussian elimination with optimal pivot element chosen - - - * **CV_SVD** Singular value decomposition (SVD) method - - - * **CV_SVD_SYM** SVD method for a symmetric positively-defined matrix. - - - - - -The function solves a linear system or least-squares problem (the latter is possible with SVD methods): - - - -.. math:: - - \texttt{dst} = argmin_X|| \texttt{src1} \, \texttt{X} - \texttt{src2} || - - -If -``CV_LU`` -method is used, the function returns 1 if -``src1`` -is non-singular and 0 otherwise; in the latter case -``dst`` -is not valid. - - -.. index:: SolveCubic - -.. _SolveCubic: - -SolveCubic ----------- - - - - - - -.. cfunction:: void cvSolveCubic(const CvArr* coeffs, CvArr* roots) - - Finds the real roots of a cubic equation. - - - - - - - :param coeffs: The equation coefficients, an array of 3 or 4 elements - - - :param roots: The output array of real roots which should have 3 elements - - - -The function finds the real roots of a cubic equation: - -If coeffs is a 4-element vector: - - - -.. math:: - - \texttt{coeffs} [0] x^3 + \texttt{coeffs} [1] x^2 + \texttt{coeffs} [2] x + \texttt{coeffs} [3] = 0 - - -or if coeffs is 3-element vector: - - - -.. math:: - - x^3 + \texttt{coeffs} [0] x^2 + \texttt{coeffs} [1] x + \texttt{coeffs} [2] = 0 - - -The function returns the number of real roots found. The roots are -stored to -``root`` -array, which is padded with zeros if there is -only one root. - - -.. index:: Split - -.. _Split: - -Split ------ - - - - - - -.. cfunction:: void cvSplit(const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3) - - Divides multi-channel array into several single-channel arrays or extracts a single channel from the array. - - - - - - - :param src: Source array - - - :param dst0: Destination channel 0 - - - :param dst1: Destination channel 1 - - - :param dst2: Destination channel 2 - - - :param dst3: Destination channel 3 - - - -The function divides a multi-channel array into separate -single-channel arrays. Two modes are available for the operation. If the -source array has N channels then if the first N destination channels -are not NULL, they all are extracted from the source array; -if only a single destination channel of the first N is not NULL, this -particular channel is extracted; otherwise an error is raised. The rest -of the destination channels (beyond the first N) must always be NULL. For -IplImage -:ref:`Copy` -with COI set can be also used to extract a single -channel from the image. - - - -.. index:: Sqrt - -.. _Sqrt: - -Sqrt ----- - - - - - - -.. cfunction:: float cvSqrt(float value) - - Calculates the square root. - - - - - - - :param value: The input floating-point value - - - -The function calculates the square root of the argument. If the argument is negative, the result is not determined. - - -.. index:: Sub - -.. _Sub: - -Sub ---- - - - - - - -.. cfunction:: void cvSub(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) - - Computes the per-element difference between two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second 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 - - - -The function subtracts one array from another one: - - - - -:: - - - - dst(I)=src1(I)-src2(I) if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). -For types that have limited range this operation is saturating. - - -.. index:: SubRS - -.. _SubRS: - -SubRS ------ - - - - - - -.. cfunction:: void cvSubRS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) - - Computes the difference between a scalar and an array. - - - - - - - :param src: The first source array - - - :param value: Scalar to subtract from - - - :param dst: The destination array - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - - -The function subtracts every element of source array from a scalar: - - - - -:: - - - - dst(I)=value-src(I) if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). -For types that have limited range this operation is saturating. - - -.. index:: SubS - -.. _SubS: - -SubS ----- - - - - - - -.. cfunction:: void cvSubS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) - - Computes the difference between an array and a scalar. - - - - - - - :param src: The source array - - - :param value: Subtracted scalar - - - :param dst: The destination array - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - - -The function subtracts a scalar from every element of the source array: - - - - -:: - - - - dst(I)=src(I)-value if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). -For types that have limited range this operation is saturating. - - - -.. index:: Sum - -.. _Sum: - -Sum ---- - - - - - - -.. cfunction:: CvScalar cvSum(const CvArr* arr) - - Adds up array elements. - - - - - - - :param arr: The array - - - -The function calculates the sum -``S`` -of array elements, independently for each channel: - - - -.. math:: - - \sum _I \texttt{arr} (I)_c - - -If the array is -``IplImage`` -and COI is set, the function processes the selected channel only and stores the sum to the first scalar component. - - - -.. index:: SVBkSb - -.. _SVBkSb: - -SVBkSb ------- - - - - - - -.. cfunction:: void cvSVBkSb( const CvArr* W, const CvArr* U, const CvArr* V, const CvArr* B, CvArr* X, int flags) - - Performs singular value back substitution. - - - - - - - :param W: Matrix or vector of singular values - - - :param U: Left orthogonal matrix (tranposed, perhaps) - - - :param V: Right orthogonal matrix (tranposed, perhaps) - - - :param B: The matrix to multiply the pseudo-inverse of the original matrix ``A`` by. This is an optional parameter. If it is omitted then it is assumed to be an identity matrix of an appropriate size (so that ``X`` will be the reconstructed pseudo-inverse of ``A`` ). - - - :param X: The destination matrix: result of back substitution - - - :param flags: Operation flags, should match exactly to the ``flags`` passed to :ref:`SVD` - - - -The function calculates back substitution for decomposed matrix -``A`` -(see -:ref:`SVD` -description) and matrix -``B`` -: - - - -.. math:: - - \texttt{X} = \texttt{V} \texttt{W} ^{-1} \texttt{U} ^T \texttt{B} - - -where - - - -.. math:: - - W^{-1}_{(i,i)}= \fork{1/W_{(i,i)}}{if $W_{(i,i)} > \epsilon \sum_i{W_{(i,i)}}$ }{0}{otherwise} - - -and -:math:`\epsilon` -is a small number that depends on the matrix data type. - -This function together with -:ref:`SVD` -is used inside -:ref:`Invert` -and -:ref:`Solve` -, and the possible reason to use these (svd and bksb) -"low-level" function, is to avoid allocation of temporary matrices inside -the high-level counterparts (inv and solve). - - -.. index:: SVD - -.. _SVD: - -SVD ---- - - - - - - -.. cfunction:: void cvSVD( CvArr* A, CvArr* W, CvArr* U=NULL, CvArr* V=NULL, int flags=0) - - Performs singular value decomposition of a real floating-point matrix. - - - - - - - :param A: Source :math:`\texttt{M} \times \texttt{N}` matrix - - - :param W: Resulting singular value diagonal matrix ( :math:`\texttt{M} \times \texttt{N}` or :math:`\min(\texttt{M}, \texttt{N}) \times \min(\texttt{M}, \texttt{N})` ) or :math:`\min(\texttt{M},\texttt{N}) \times 1` vector of the singular values - - - :param U: Optional left orthogonal matrix, :math:`\texttt{M} \times \min(\texttt{M}, \texttt{N})` (when ``CV_SVD_U_T`` is not set), or :math:`\min(\texttt{M},\texttt{N}) \times \texttt{M}` (when ``CV_SVD_U_T`` is set), or :math:`\texttt{M} \times \texttt{M}` (regardless of ``CV_SVD_U_T`` flag). - - - :param V: Optional right orthogonal matrix, :math:`\texttt{N} \times \min(\texttt{M}, \texttt{N})` (when ``CV_SVD_V_T`` is not set), or :math:`\min(\texttt{M},\texttt{N}) \times \texttt{N}` (when ``CV_SVD_V_T`` is set), or :math:`\texttt{N} \times \texttt{N}` (regardless of ``CV_SVD_V_T`` flag). - - - :param flags: Operation flags; can be 0 or a combination of the following values: - - - * **CV_SVD_MODIFY_A** enables modification of matrix ``A`` during the operation. It speeds up the processing. - - - * **CV_SVD_U_T** means that the transposed matrix ``U`` is returned. Specifying the flag speeds up the processing. - - - * **CV_SVD_V_T** means that the transposed matrix ``V`` is returned. Specifying the flag speeds up the processing. - - - - - -The function decomposes matrix -``A`` -into the product of a diagonal matrix and two - -orthogonal matrices: - - - -.. math:: - - A=U \, W \, V^T - - -where -:math:`W` -is a diagonal matrix of singular values that can be coded as a -1D vector of singular values and -:math:`U` -and -:math:`V` -. All the singular values -are non-negative and sorted (together with -:math:`U` -and -:math:`V` -columns) -in descending order. - -An SVD algorithm is numerically robust and its typical applications include: - - - - - -* - accurate eigenvalue problem solution when matrix - ``A`` - is a square, symmetric, and positively defined matrix, for example, when - it is a covariance matrix. - :math:`W` - in this case will be a vector/matrix - of the eigenvalues, and - :math:`U = V` - will be a matrix of the eigenvectors. - - - -* - accurate solution of a poor-conditioned linear system. - - - -* - least-squares solution of an overdetermined linear system. This and the preceeding is done by using the - :ref:`Solve` - function with the - ``CV_SVD`` - method. - - - -* - accurate calculation of different matrix characteristics such as the matrix rank (the number of non-zero singular values), condition number (ratio of the largest singular value to the smallest one), and determinant (absolute value of the determinant is equal to the product of singular values). - - - -.. index:: Trace - -.. _Trace: - -Trace ------ - - - - - - -.. cfunction:: CvScalar cvTrace(const CvArr* mat) - - Returns the trace of a matrix. - - - - - - - :param mat: The source matrix - - - -The function returns the sum of the diagonal elements of the matrix -``src1`` -. - - - -.. math:: - - tr( \texttt{mat} ) = \sum _i \texttt{mat} (i,i) - - - -.. index:: Transform - -.. _Transform: - -Transform ---------- - - - - - - -.. cfunction:: void cvTransform(const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL) - - Performs matrix transformation of every array element. - - - - - - - :param src: The first source array - - - :param dst: The destination array - - - :param transmat: Transformation matrix - - - :param shiftvec: Optional shift vector - - - -The function performs matrix transformation of every element of array -``src`` -and stores the results in -``dst`` -: - - - -.. math:: - - dst(I) = transmat \cdot src(I) + shiftvec - - -That is, every element of an -``N`` --channel array -``src`` -is -considered as an -``N`` --element vector which is transformed using -a -:math:`\texttt{M} \times \texttt{N}` -matrix -``transmat`` -and shift -vector -``shiftvec`` -into an element of -``M`` --channel array -``dst`` -. There is an option to embedd -``shiftvec`` -into -``transmat`` -. In this case -``transmat`` -should be a -:math:`\texttt{M} -\times (N+1)` -matrix and the rightmost column is treated as the shift -vector. - -Both source and destination arrays should have the same depth and the -same size or selected ROI size. -``transmat`` -and -``shiftvec`` -should be real floating-point matrices. - -The function may be used for geometrical transformation of n dimensional -point set, arbitrary linear color space transformation, shuffling the -channels and so forth. - - -.. index:: Transpose - -.. _Transpose: - -Transpose ---------- - - - - - - -.. cfunction:: void cvTranspose(const CvArr* src, CvArr* dst) - - Transposes a matrix. - - - - - - - :param src: The source matrix - - - :param dst: The destination matrix - - - -The function transposes matrix -``src1`` -: - - - -.. math:: - - \texttt{dst} (i,j) = \texttt{src} (j,i) - - -Note that no complex conjugation is done in the case of a complex -matrix. Conjugation should be done separately: look at the sample code -in -:ref:`XorS` -for an example. - - -.. index:: Xor - -.. _Xor: - -Xor ---- - - - - - - -.. cfunction:: void cvXor(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL) - - Performs per-element bit-wise "exclusive or" operation on two arrays. - - - - - - - :param src1: The first source array - - - :param src2: The second 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 - - - -The function calculates per-element bit-wise logical conjunction of two arrays: - - - - -:: - - - - dst(I)=src1(I)^src2(I) if mask(I)!=0 - - -.. - -In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - -.. index:: XorS - -.. _XorS: - -XorS ----- - - - - - - -.. cfunction:: void cvXorS(const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL) - - Performs per-element bit-wise "exclusive or" operation on an array and a scalar. - - - - - - - :param src: The source array - - - :param value: Scalar to use in the operation - - - :param dst: The destination array - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - - -The function XorS calculates per-element bit-wise conjunction of an array and a scalar: - - - - -:: - - - - dst(I)=src(I)^value if mask(I)!=0 - - -.. - -Prior to the actual operation, the scalar is converted to the same type as that of the array(s). In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size - -The following sample demonstrates how to conjugate complex vector by switching the most-significant bit of imaging part: - - - - -:: - - - - - float a[] = { 1, 0, 0, 1, -1, 0, 0, -1 }; /* 1, j, -1, -j */ - CvMat A = cvMat(4, 1, CV_32FC2, &a); - int i, negMask = 0x80000000; - cvXorS(&A, cvScalar(0, *(float*)&negMask, 0, 0 ), &A, 0); - for(i = 0; i < 4; i++ ) - printf("(%.1f, %.1f) ", a[i*2], a[i*2+1]); - - - -.. - -The code should print: - - - - -:: - - - - (1.0,0.0) (0.0,-1.0) (-1.0,0.0) (0.0,1.0) - - -.. - - -.. index:: mGet - -.. _mGet: - -mGet ----- - - - - - - -.. cfunction:: double cvmGet(const CvMat* mat, int row, int col) - - Returns the particular element of single-channel floating-point matrix. - - - - - - - :param mat: Input matrix - - - :param row: The zero-based index of row - - - :param col: The zero-based index of column - - - -The function is a fast replacement for -:ref:`GetReal2D` -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. - - -.. index:: mSet - -.. _mSet: - -mSet ----- - - - - - - -.. cfunction:: void cvmSet(CvMat* mat, int row, int col, double value) - - Sets a specific element of a single-channel floating-point matrix. - - - - - - - :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 - - - -The function is a fast replacement for -:ref:`SetReal2D` -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. - diff --git a/doc/opencv1/c/core_utility_and_system_functions_and_macros.rst b/doc/opencv1/c/core_utility_and_system_functions_and_macros.rst deleted file mode 100644 index 2518381187..0000000000 --- a/doc/opencv1/c/core_utility_and_system_functions_and_macros.rst +++ /dev/null @@ -1,993 +0,0 @@ -Utility and System Functions and Macros -======================================= - -.. highlight:: c - - - -Error Handling --------------- - - -Error handling in OpenCV is similar to IPL (Image Processing -Library). In the case of an error, functions do not return the error -code. Instead, they raise an error using -``CV_ERROR`` -macro that calls -:ref:`Error` -that, in its turn, sets the error -status with -:ref:`SetErrStatus` -and calls a standard or user-defined -error handler (that can display a message box, write to log, etc., see -:ref:`RedirectError` -). There is a global variable, one per each program -thread, that contains current error status (an integer value). The status -can be retrieved with the -:ref:`GetErrStatus` -function. - -There are three modes of error handling (see -:ref:`SetErrMode` -and -:ref:`GetErrMode` -): - - - - - -* - **Leaf** - . The program is terminated after the error handler is - called. This is the default value. It is useful for debugging, as the - error is signalled immediately after it occurs. However, for production - systems, other two methods may be preferable as they provide more - control. - - -* - **Parent** - . The program is not terminated, but the error handler - is called. The stack is unwound (it is done w/o using a C++ exception - mechanism). The user may check error code after calling the - ``CxCore`` - function with - :ref:`GetErrStatus` - and react. - - -* - **Silent** - . Similar to - ``Parent`` - mode, but no error handler - is called. - - -Actually, the semantics of the -``Leaf`` -and -``Parent`` -modes are implemented by error handlers and the above description is true for them. -:ref:`GuiBoxReport` -behaves slightly differently, and some custom error handlers may implement quite different semantics. - -Macros for raising an error, checking for errors, etc. - - - -:: - - - - - /* special macros for enclosing processing statements within a function and separating - them from prologue (resource initialization) and epilogue (guaranteed resource release) */ - #define __BEGIN__ { - #define __END__ goto exit; exit: ; } - /* proceeds to "resource release" stage */ - #define EXIT goto exit - - /* Declares locally the function name for CV_ERROR() use */ - #define CV_FUNCNAME( Name ) \ - static char cvFuncName[] = Name - - /* Raises an error within the current context */ - #define CV_ERROR( Code, Msg ) \ - - - /* Checks status after calling CXCORE function */ - #define CV_CHECK() \ - - - /* Provies shorthand for CXCORE function call and CV_CHECK() */ - #define CV_CALL( Statement ) \ - - - /* Checks some condition in both debug and release configurations */ - #define CV_ASSERT( Condition ) \ - - - /* these macros are similar to their CV_... counterparts, but they - do not need exit label nor cvFuncName to be defined */ - #define OPENCV_ERROR(status,func_name,err_msg) ... - #define OPENCV_ERRCHK(func_name,err_msg) ... - #define OPENCV_ASSERT(condition,func_name,err_msg) ... - #define OPENCV_CALL(statement) ... - - - -.. - -Instead of a discussion, below is a documented example of a typical CXCORE function and an example of the function use. - - -Example: Use of Error Handling Macros -------------------------------------- - - - - - -:: - - - - - #include "cxcore.h" - #include - - void cvResizeDCT( CvMat* input_array, CvMat* output_array ) - { - CvMat* temp_array = 0; // declare pointer that should be released anyway. - - CV_FUNCNAME( "cvResizeDCT" ); // declare cvFuncName - - __BEGIN__; // start processing. There may be some declarations just after - // this macro, but they could not be accessed from the epilogue. - - if( !CV_IS_MAT(input_array) || !CV_IS_MAT(output_array) ) - // use CV_ERROR() to raise an error - CV_ERROR( CV_StsBadArg, - "input_array or output_array are not valid matrices" ); - - // some restrictions that are going to be removed later, may be checked - // with CV_ASSERT() - CV_ASSERT( input_array->rows == 1 && output_array->rows == 1 ); - - // use CV_CALL for safe function call - CV_CALL( temp_array = cvCreateMat( input_array->rows, - MAX(input_array->cols, - output_array->cols), - input_array->type )); - - if( output_array->cols > input_array->cols ) - CV_CALL( cvZero( temp_array )); - - temp_array->cols = input_array->cols; - CV_CALL( cvDCT( input_array, temp_array, CV_DXT_FORWARD )); - temp_array->cols = output_array->cols; - CV_CALL( cvDCT( temp_array, output_array, CV_DXT_INVERSE )); - CV_CALL( cvScale( output_array, - output_array, - 1./sqrt((double)input_array->cols*output_array->cols), 0 )); - - __END__; // finish processing. Epilogue follows after the macro. - - // release temp_array. If temp_array has not been allocated - // before an error occured, cvReleaseMat - // takes care of it and does nothing in this case. - cvReleaseMat( &temp_array ); - } - - int main( int argc, char** argv ) - { - CvMat* src = cvCreateMat( 1, 512, CV_32F ); - #if 1 /* no errors */ - CvMat* dst = cvCreateMat( 1, 256, CV_32F ); - #else - CvMat* dst = 0; /* test error processing mechanism */ - #endif - cvSet( src, cvRealScalar(1.), 0 ); - #if 0 /* change 0 to 1 to suppress error handler invocation */ - cvSetErrMode( CV_ErrModeSilent ); - #endif - cvResizeDCT( src, dst ); // if some error occurs, the message - // box will popup, or a message will be - // written to log, or some user-defined - // processing will be done - if( cvGetErrStatus() < 0 ) - printf("Some error occured" ); - else - printf("Everything is OK" ); - return 0; - } - - -.. - - -.. index:: GetErrStatus - -.. _GetErrStatus: - -GetErrStatus ------------- - - - - - - -.. cfunction:: int cvGetErrStatus( void ) - - Returns the current error status. - - - -The function returns the current error status - -the value set with the last -:ref:`SetErrStatus` -call. Note that in -``Leaf`` -mode, the program terminates immediately after an -error occurs, so to always gain control after the function call, -one should call -:ref:`SetErrMode` -and set the -``Parent`` -or -``Silent`` -error mode. - - -.. index:: SetErrStatus - -.. _SetErrStatus: - -SetErrStatus ------------- - - - - - - -.. cfunction:: void cvSetErrStatus( int status ) - - Sets the error status. - - - - - - - :param status: The error status - - - -The function sets the error status to the specified value. Mostly, the function is used to reset the error status (set to it -``CV_StsOk`` -) to recover after an error. In other cases it is more natural to call -:ref:`Error` -or -``CV_ERROR`` -. - - -.. index:: GetErrMode - -.. _GetErrMode: - -GetErrMode ----------- - - - - - - -.. cfunction:: int cvGetErrMode(void) - - Returns the current error mode. - - - -The function returns the current error mode - the value set with the last -:ref:`SetErrMode` -call. - - -.. index:: SetErrMode - -.. _SetErrMode: - -SetErrMode ----------- - - - - - - - -:: - - - - - -.. - - - -.. cfunction:: int cvSetErrMode( int mode ) - - Sets the error mode. - -#define CV_ErrModeLeaf 0 -#define CV_ErrModeParent 1 -#define CV_ErrModeSilent 2 - - - - - - :param mode: The error mode - - - -The function sets the specified error mode. For descriptions of different error modes, see the beginning of the error section. - - -.. index:: Error - -.. _Error: - -Error ------ - - - - - - -.. cfunction:: int cvError( int status, const char* func_name, const char* err_msg, const char* filename, int line ) - - Raises an error. - - - - - - - :param status: The error status - - - :param func_name: Name of the function where the error occured - - - :param err_msg: Additional information/diagnostics about the error - - - :param filename: Name of the file where the error occured - - - :param line: Line number, where the error occured - - - -The function sets the error status to the specified value (via -:ref:`SetErrStatus` -) and, if the error mode is not -``Silent`` -, calls the error handler. - - -.. index:: ErrorStr - -.. _ErrorStr: - -ErrorStr --------- - - - - - - -.. cfunction:: const char* cvErrorStr( int status ) - - Returns textual description of an error status code. - - - - - - - :param status: The error status - - - -The function returns the textual description for -the specified error status code. In the case of unknown status, the function -returns a NULL pointer. - - -.. index:: RedirectError - -.. _RedirectError: - -RedirectError -------------- - - - - - - -.. cfunction:: CvErrorCallback cvRedirectError( CvErrorCallback error_handler, void* userdata=NULL, void** prevUserdata=NULL ) - - Sets a new error handler. - - - - - - - - :param error_handler: The new error _ handler - - - :param userdata: Arbitrary pointer that is transparently passed to the error handler - - - :param prevUserdata: Pointer to the previously assigned user data pointer - - - - - - -:: - - - - typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name, - const char* err_msg, const char* file_name, int line ); - - -.. - -The function sets a new error handler that -can be one of the standard handlers or a custom handler -that has a specific interface. The handler takes the same parameters -as the -:ref:`Error` -function. If the handler returns a non-zero value, the -program is terminated; otherwise, it continues. The error handler may -check the current error mode with -:ref:`GetErrMode` -to make a decision. - - - -.. index:: cvNulDevReport cvStdErrReport cvGuiBoxReport - -.. _cvNulDevReport cvStdErrReport cvGuiBoxReport: - -cvNulDevReport cvStdErrReport cvGuiBoxReport --------------------------------------------- - - - - - - -.. cfunction:: int cvNulDevReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ) - - - -.. cfunction:: int cvStdErrReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ) - - - -.. cfunction:: int cvGuiBoxReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ) - - Provide standard error handling. - - - - - - - :param status: The error status - - - :param func_name: Name of the function where the error occured - - - :param err_msg: Additional information/diagnostics about the error - - - :param filename: Name of the file where the error occured - - - :param line: Line number, where the error occured - - - :param userdata: Pointer to the user data. Ignored by the standard handlers - - - -The functions -``cvNullDevReport`` -, -``cvStdErrReport`` -, -and -``cvGuiBoxReport`` -provide standard error -handling. -``cvGuiBoxReport`` -is the default error -handler on Win32 systems, -``cvStdErrReport`` -is the default on other -systems. -``cvGuiBoxReport`` -pops up a message box with the error -description and suggest a few options. Below is an example message box -that may be recieved with the sample code above, if one introduces an -error as described in the sample. - -**Error Message Box** - - -.. image:: ../pics/errmsg.png - - - -If the error handler is set to -``cvStdErrReport`` -, the above message will be printed to standard error output and the program will be terminated or continued, depending on the current error mode. - -**Error Message printed to Standard Error Output (in ``Leaf`` mode)** - - - -:: - - - - OpenCV ERROR: Bad argument (input_array or output_array are not valid matrices) - in function cvResizeDCT, D:UserVPProjectsavl_probaa.cpp(75) - Terminating the application... - - -.. - - -.. index:: Alloc - -.. _Alloc: - -Alloc ------ - - - - - - -.. cfunction:: void* cvAlloc( size_t size ) - - Allocates a memory buffer. - - - - - - - :param size: Buffer size in bytes - - - -The function allocates -``size`` -bytes and returns -a pointer to the allocated buffer. In the case of an error the function reports an -error and returns a NULL pointer. By default, -``cvAlloc`` -calls -``icvAlloc`` -which -itself calls -``malloc`` -. However it is possible to assign user-defined memory -allocation/deallocation functions using the -:ref:`SetMemoryManager` -function. - - -.. index:: Free - -.. _Free: - -Free ----- - - - - - - -.. cfunction:: void cvFree( void** ptr ) - - Deallocates a memory buffer. - - - - - - - :param ptr: Double pointer to released buffer - - - -The function deallocates a memory buffer allocated by -:ref:`Alloc` -. It clears the pointer to buffer upon exit, which is why -the double pointer is used. If the -``*buffer`` -is already NULL, the function -does nothing. - - -.. index:: GetTickCount - -.. _GetTickCount: - -GetTickCount ------------- - - - - - - -.. cfunction:: int64 cvGetTickCount( void ) - - Returns the number of ticks. - - - -The function returns number of the ticks starting from some platform-dependent event (number of CPU ticks from the startup, number of milliseconds from 1970th year, etc.). The function is useful for accurate measurement of a function/user-code execution time. To convert the number of ticks to time units, use -:ref:`GetTickFrequency` -. - - -.. index:: GetTickFrequency - -.. _GetTickFrequency: - -GetTickFrequency ----------------- - - - - - - -.. cfunction:: double cvGetTickFrequency( void ) - - Returns the number of ticks per microsecond. - - - -The function returns the number of ticks per microsecond. Thus, the quotient of -:ref:`GetTickCount` -and -:ref:`GetTickFrequency` -will give the number of microseconds starting from the platform-dependent event. - - -.. index:: RegisterModule - -.. _RegisterModule: - -RegisterModule --------------- - - - - - - - -:: - - - - - -.. - - - -.. cfunction:: int cvRegisterModule( const CvModuleInfo* moduleInfo ) - - Registers another module. - -typedef struct CvPluginFuncInfo -{ - void** func_addr; - void* default_func_addr; - const char* func_names; - int search_modules; - int loaded_from; -} -CvPluginFuncInfo; - -typedef struct CvModuleInfo -{ - struct CvModuleInfo* next; - const char* name; - const char* version; - CvPluginFuncInfo* func_tab; -} -CvModuleInfo; - - - - - - :param moduleInfo: Information about the module - - - -The function adds a module to the list of -registered modules. After the module is registered, information about -it can be retrieved using the -:ref:`GetModuleInfo` -function. Also, the -registered module makes full use of optimized plugins (IPP, MKL, ...), -supported by CXCORE. CXCORE itself, CV (computer vision), CVAUX (auxilary -computer vision), and HIGHGUI (visualization and image/video acquisition) are -examples of modules. Registration is usually done when the shared library -is loaded. See -``cxcore/src/cxswitcher.cpp`` -and -``cv/src/cvswitcher.cpp`` -for details about how registration is done -and look at -``cxcore/src/cxswitcher.cpp`` -, -``cxcore/src/_cxipp.h`` -on how IPP and MKL are connected to the modules. - - -.. index:: GetModuleInfo - -.. _GetModuleInfo: - -GetModuleInfo -------------- - - - - - - -.. cfunction:: void cvGetModuleInfo( const char* moduleName, const char** version, const char** loadedAddonPlugins) - - Retrieves information about registered module(s) and plugins. - - - - - - - :param moduleName: Name of the module of interest, or NULL, which means all the modules - - - :param version: The output parameter. Information about the module(s), including version - - - :param loadedAddonPlugins: The list of names and versions of the optimized plugins that CXCORE was able to find and load - - - -The function returns information about one or -all of the registered modules. The returned information is stored inside -the libraries, so the user should not deallocate or modify the returned -text strings. - - -.. index:: UseOptimized - -.. _UseOptimized: - -UseOptimized ------------- - - - - - - -.. cfunction:: int cvUseOptimized( int onoff ) - - Switches between optimized/non-optimized modes. - - - - - - - :param onoff: Use optimized ( :math:`\ne 0` ) or not ( :math:`=0` ) - - - -The function switches between the mode, where -only pure C implementations from cxcore, OpenCV, etc. are used, and -the mode, where IPP and MKL functions are used if available. When -``cvUseOptimized(0)`` -is called, all the optimized libraries are -unloaded. The function may be useful for debugging, IPP and MKL upgrading on -the fly, online speed comparisons, etc. It returns the number of optimized -functions loaded. Note that by default, the optimized plugins are loaded, -so it is not necessary to call -``cvUseOptimized(1)`` -in the beginning of -the program (actually, it will only increase the startup time). - - -.. index:: SetMemoryManager - -.. _SetMemoryManager: - -SetMemoryManager ----------------- - - - - - - - -:: - - - - - -.. - - - -.. cfunction:: void cvSetMemoryManager( CvAllocFunc allocFunc=NULL, CvFreeFunc freeFunc=NULL, void* userdata=NULL ) - - Accesses custom/default memory managing functions. - -typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata); -typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata); - - - - - - :param allocFunc: Allocation function; the interface is similar to ``malloc`` , except that ``userdata`` may be used to determine the context - - - :param freeFunc: Deallocation function; the interface is similar to ``free`` - - - :param userdata: User data that is transparently passed to the custom functions - - - -The function sets user-defined memory -managment functions (substitutes for -``malloc`` -and -``free`` -) that will be called -by -``cvAlloc, cvFree`` -and higher-level functions (e.g., -``cvCreateImage`` -). Note -that the function should be called when there is data allocated using -``cvAlloc`` -. Also, to avoid infinite recursive calls, it is not -allowed to call -``cvAlloc`` -and -:ref:`Free` -from the custom -allocation/deallocation functions. - -If the -``alloc_func`` -and -``free_func`` -pointers are -``NULL`` -, the default memory managing functions are restored. - - -.. index:: SetIPLAllocators - -.. _SetIPLAllocators: - -SetIPLAllocators ----------------- - - - - - - - -:: - - - \ - \ - - - -.. - - - -.. cfunction:: void cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, Cv_iplAllocateImageData allocate_data, Cv_iplDeallocate deallocate, Cv_iplCreateROI create_roi, Cv_iplCloneImage clone_image ) - - Switches to IPL functions for image allocation/deallocation. - -typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader) - (int,int,int,char*,char*,int,int,int,int,int, - IplROI*,IplImage*,void*,IplTileInfo*); -typedef void (CV_STDCALL* Cv_iplAllocateImageData)(IplImage*,int,int); -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*); - -#define CV_TURN_ON_IPL_COMPATIBILITY() cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage, iplDeallocate, iplCreateROI, iplCloneImage ) - - - - - - :param create_header: Pointer to iplCreateImageHeader - - - :param allocate_data: Pointer to iplAllocateImage - - - :param deallocate: Pointer to iplDeallocate - - - :param create_roi: Pointer to iplCreateROI - - - :param clone_image: Pointer to iplCloneImage - - - -The function causes CXCORE to use IPL functions -for image allocation/deallocation operations. For convenience, there -is the wrapping macro -``CV_TURN_ON_IPL_COMPATIBILITY`` -. The -function is useful for applications where IPL and CXCORE/OpenCV are used -together and still there are calls to -``iplCreateImageHeader`` -, -etc. The function is not necessary if IPL is called only for data -processing and all the allocation/deallocation is done by CXCORE, or -if all the allocation/deallocation is done by IPL and some of OpenCV -functions are used to process the data. - diff --git a/doc/opencv1/c/core_xml_yaml_persistence.rst b/doc/opencv1/c/core_xml_yaml_persistence.rst deleted file mode 100644 index 60e9d265ca..0000000000 --- a/doc/opencv1/c/core_xml_yaml_persistence.rst +++ /dev/null @@ -1,2064 +0,0 @@ -XML/YAML Persistence -==================== - -.. highlight:: c - - - -.. index:: CvFileStorage - -.. _CvFileStorage: - -CvFileStorage -------------- - - - -.. ctype:: CvFileStorage - - - -File Storage. - - - - -:: - - - - typedef struct CvFileStorage - { - ... // hidden fields - } CvFileStorage; - - -.. - -The structure -:ref:`CvFileStorage` -is a "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 theuser to save or to load hierarchical collections -that consist of scalar values, standard CXCore objects (such as -matrices, sequences, graphs), and user-defined objects. - -CXCore can read and write data in XML (http://www.w3c.org/XML) or YAML -(http://www.yaml.org) formats. Below is an example of -:math:`3 \times 3` -floating-point identity matrix -``A`` -, stored in XML and YAML files -using CXCore functions: - -XML: - -:: - - - - - 3 - 3 -
f
- 1. 0. 0. 0. 1. 0. 0. 0. 1. -
-
- - -YAML: - -:: - - A: !!opencv-matrix - rows: 3 - cols: 3 - dt: f - data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.] - - -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 CXCore 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. - - - -.. index:: CvFileNode - -.. _CvFileNode: - -CvFileNode ----------- - - - -.. ctype:: CvFileNode - - - -File Storage Node. - - - - -:: - - - - /* file node type */ - #define CV_NODE_NONE 0 - #define CV_NODE_INT 1 - #define CV_NODE_INTEGER CV_NODE_INT - #define CV_NODE_REAL 2 - #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_SEQ 5 - #define CV_NODE_MAP 6 - #define CV_NODE_TYPE_MASK 7 - - /* optional flags */ - #define CV_NODE_USER 16 - #define CV_NODE_EMPTY 32 - #define CV_NODE_NAMED 64 - - #define CV_NODE_TYPE(tag) ((tag) & CV_NODE_TYPE_MASK) - - #define CV_NODE_IS_INT(tag) (CV_NODE_TYPE(tag) == CV_NODE_INT) - #define CV_NODE_IS_REAL(tag) (CV_NODE_TYPE(tag) == CV_NODE_REAL) - #define CV_NODE_IS_STRING(tag) (CV_NODE_TYPE(tag) == CV_NODE_STRING) - #define CV_NODE_IS_SEQ(tag) (CV_NODE_TYPE(tag) == CV_NODE_SEQ) - #define CV_NODE_IS_MAP(tag) (CV_NODE_TYPE(tag) == CV_NODE_MAP) - #define CV_NODE_IS_COLLECTION(tag) (CV_NODE_TYPE(tag) >= CV_NODE_SEQ) - #define CV_NODE_IS_FLOW(tag) (((tag) & CV_NODE_FLOW) != 0) - #define CV_NODE_IS_EMPTY(tag) (((tag) & CV_NODE_EMPTY) != 0) - #define CV_NODE_IS_USER(tag) (((tag) & CV_NODE_USER) != 0) - #define CV_NODE_HAS_NAME(tag) (((tag) & CV_NODE_NAMED) != 0) - - #define CV_NODE_SEQ_SIMPLE 256 - #define CV_NODE_SEQ_IS_SIMPLE(seq) (((seq)->flags & CV_NODE_SEQ_SIMPLE) != 0) - - typedef struct CvString - { - int len; - char* ptr; - } - CvString; - - /* all the keys (names) of elements in the readed file storage - are stored in the hash to speed up the lookup operations */ - typedef struct CvStringHashNode - { - unsigned hashval; - CvString str; - struct CvStringHashNode* next; - } - CvStringHashNode; - - /* basic element of the file storage - scalar or collection */ - typedef struct CvFileNode - { - int tag; - struct CvTypeInfo* info; /* type information - (only for user-defined object, for others it is 0) */ - union - { - double f; /* scalar floating-point number */ - int i; /* scalar integer number */ - CvString str; /* text string */ - CvSeq* seq; /* sequence (ordered collection of file nodes) */ - struct CvMap* map; /* map (collection of named file nodes) */ - } data; - } - CvFileNode; - - -.. - -The structure is used only for retrieving data from file storage -(i.e., for loading data from the file). When data is written to a file, -it is done sequentially, with minimal buffering. No data is stored -in the file storage. - -In opposite, when data is read from a file, the whole file is parsed -and represented in memory as a tree. Every node of the tree is -represented by -:ref:`CvFileNode` -. The type of file node -``N`` -can be retrieved as -``CV_NODE_TYPE(N->tag)`` -. Some file nodes -(leaves) are scalars: text strings, integers, or floating-point -numbers. Other file nodes are collections of file nodes, which can -be scalars or collections in their turn. There are two types of -collections: sequences and maps (we use YAML notation, however, the -same is true for XML streams). Sequences (do not mix them with -:ref:`CvSeq` -) are ordered collections of unnamed file nodes; maps -are unordered collections of named file nodes. Thus, elements of -sequences are accessed by index ( -:ref:`GetSeqElem` -), while elements -of maps are accessed by name ( -:ref:`GetFileNodeByName` -). The table -below describes the different types of file nodes: - - -.. table:: - - ============== =========================== ================================ - Type ``CV_NODE_TYPE(node->tag)`` Value \ - ============== =========================== ================================ - Integer ``CV_NODE_INT`` ``node->data.i`` \ - Floating-point ``CV_NODE_REAL`` ``node->data.f`` \ - Text string ``CV_NODE_STR`` ``node->data.str.ptr`` \ - Sequence ``CV_NODE_SEQ`` ``node->data.seq`` \ - Map ``CV_NODE_MAP`` ``node->data.map`` (see below) \ - ============== =========================== ================================ - -There is no need to access the -``map`` -field directly (by the way, -``CvMap`` -is a hidden structure). The elements of the map can -be retrieved with the -:ref:`GetFileNodeByName` -function that takes a -pointer to the "map" file node. - -A user (custom) object is an instance of either one of the standard CxCore -types, such as -:ref:`CvMat` -, -:ref:`CvSeq` -etc., or any type -registered with -:ref:`RegisterTypeInfo` -. Such an object is initially -represented in a file as a map (as shown in XML and YAML example files -above) after the file storage has been opened and parsed. Then the -object can be decoded (coverted to native representation) by -request - when a user calls the -:ref:`Read` -or -:ref:`ReadByName` -functions. - - - -.. index:: CvAttrList - -.. _CvAttrList: - -CvAttrList ----------- - - - -.. ctype:: CvAttrList - - - -List of attributes. - - - - -:: - - - - 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 */ - } - CvAttrList; - - /* initializes CvAttrList structure */ - inline CvAttrList cvAttrList( const char** attr=NULL, CvAttrList* next=NULL ); - - /* returns attribute value or 0 (NULL) if there is no such attribute */ - const char* cvAttrValue( const CvAttrList* attr, const char* attr_name ); - - -.. - -In the current implementation, attributes are used to pass extra parameters when writing user objects (see -:ref:`Write` -). XML attributes inside tags are not supported, aside from the object type specification ( -``type_id`` -attribute). - - - -.. index:: CvTypeInfo - -.. _CvTypeInfo: - -CvTypeInfo ----------- - - - -.. ctype:: CvTypeInfo - - - -Type information. - - - - -:: - - - - typedef int (CV_CDECL *CvIsInstanceFunc)( const void* structPtr ); - typedef void (CV_CDECL *CvReleaseFunc)( void** structDblPtr ); - typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node ); - typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, - const char* name, - const void* structPtr, - CvAttrList attributes ); - typedef void* (CV_CDECL *CvCloneFunc)( const void* structPtr ); - - typedef struct CvTypeInfo - { - int flags; /* not used */ - int header_size; /* sizeof(CvTypeInfo) */ - struct CvTypeInfo* prev; /* previous registered type in the list */ - struct CvTypeInfo* next; /* next registered type in the list */ - const char* type_name; /* type name, written to file storage */ - - /* methods */ - CvIsInstanceFunc is_instance; /* checks if the passed object belongs to the type */ - CvReleaseFunc release; /* releases object (memory etc.) */ - CvReadFunc read; /* reads object from file storage */ - CvWriteFunc write; /* writes object to file storage */ - CvCloneFunc clone; /* creates a copy of the object */ - } - CvTypeInfo; - - - -.. - -The structure -:ref:`CvTypeInfo` -contains information about one of the -standard or user-defined types. Instances of the type may or may not -contain a pointer to the corresponding -:ref:`CvTypeInfo` -structure. In -any case, there is a way to find the type info structure for a given object -using the -:ref:`TypeOf` -function. Aternatively, type info can be found by -type name using -:ref:`FindType` -, which is used when an object is read -from file storage. The user can register a new type with -:ref:`RegisterType` -that adds the type information structure into the beginning of the type -list. Thus, it is possible to create specialized types from generic -standard types and override the basic methods. - - - -.. index:: Clone - -.. _Clone: - -Clone ------ - - - - - - -.. cfunction:: void* cvClone( const void* structPtr ) - - Makes a clone of an object. - - - - - - - :param structPtr: The object to clone - - - -The function finds the type of a given object and calls -``clone`` -with the passed object. - - -.. index:: EndWriteStruct - -.. _EndWriteStruct: - -EndWriteStruct --------------- - - - - - - -.. cfunction:: void cvEndWriteStruct(CvFileStorage* fs) - - Ends the writing of a structure. - - - - - - - :param fs: File storage - - - -The function finishes the currently written structure. - - -.. index:: FindType - -.. _FindType: - -FindType --------- - - - - - - -.. cfunction:: CvTypeInfo* cvFindType(const char* typeName) - - Finds a type by its name. - - - - - - - :param typeName: Type name - - - -The function finds a registered type by its name. It returns NULL if there is no type with the specified name. - - - -.. index:: FirstType - -.. _FirstType: - -FirstType ---------- - - - - - - -.. cfunction:: CvTypeInfo* cvFirstType(void) - - 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 -:ref:`CvTypeInfo` -structure. - - -.. index:: GetFileNode - -.. _GetFileNode: - -GetFileNode ------------ - - - - - - -.. cfunction:: CvFileNode* cvGetFileNode( CvFileStorage* fs, CvFileNode* map, const CvStringHashNode* key, int createMissing=0 ) - - Finds a node in a map or file storage. - - - - - - - :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 :ref:`GetHashedKey` - - - :param createMissing: Flag that specifies whether an absent node should be added to the map - - - -The function finds a file node. It is a faster version of -:ref:`GetFileNodeByName` -(see -:ref:`GetHashedKey` -discussion). Also, the function can insert a new node, if it is not in the map yet. - - -.. index:: GetFileNodeByName - -.. _GetFileNodeByName: - -GetFileNodeByName ------------------ - - - - - - -.. cfunction:: CvFileNode* cvGetFileNodeByName( const CvFileStorage* fs, const CvFileNode* map, const char* name) - - Finds a node in a map or file storage. - - - - - - - :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 - - - -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 -:ref:`GetSeqElem` -(or sequence reader) -for sequences, it is possible to nagivate 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 -:ref:`GetHashedKey` -and -:ref:`GetFileNode` -. - - -.. index:: GetFileNodeName - -.. _GetFileNodeName: - -GetFileNodeName ---------------- - - - - - - -.. cfunction:: const char* cvGetFileNodeName( const CvFileNode* node ) - - Returns the name of a file node. - - - - - - - :param node: 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`` -. - - - -.. index:: GetHashedKey - -.. _GetHashedKey: - -GetHashedKey ------------- - - - - - - -.. cfunction:: CvStringHashNode* cvGetHashedKey( CvFileStorage* fs, const char* name, int len=-1, int createMissing=0 ) - - Returns a unique pointer for a given name. - - - - - - - :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 createMissing: Flag that specifies, whether an absent key should be added into the hash table - - - -The function returns a unique pointer for -each particular file node name. This pointer can be then passed to the -:ref:`GetFileNode` -function that is faster than -:ref:`GetFileNodeByName` -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: - - - - -:: - - - - - - points: - - { x: 10, y: 10 } - - { x: 20, y: 20 } - - { x: 30, y: 30 } - # ... - - - -.. - -Then, it is possible to get hashed "x" and "y" pointers to speed up decoding of the points. - - - - - -:: - - - - - #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 /* default value */ ); - int y = cvReadIntByName( fs, pt, "y", 0 /* default value */ ); - #endif - CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); - printf(" - } - } - cvReleaseFileStorage( &fs ); - return 0; - } - - - -.. - -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. - - -.. index:: GetRootFileNode - -.. _GetRootFileNode: - -GetRootFileNode ---------------- - - - - - - -.. cfunction:: CvFileNode* cvGetRootFileNode( const CvFileStorage* fs, int stream_index=0 ) - - Retrieves one of the top-level nodes of the file storage. - - - - - - - :param fs: File storage - - - :param stream_index: Zero-based index of the stream. See :ref:`StartNextStream` . In most cases, there is only one stream in the file; however, there can be several. - - - -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 may be iterated by subsequent calls to the function with -``stream_index=0,1,...`` -, until the NULL pointer is returned. This function -may be used as a base for recursive traversal of the file storage. - - -.. index:: Load - -.. _Load: - -Load ----- - - - - - - -.. cfunction:: void* cvLoad( const char* filename, CvMemStorage* storage=NULL, const char* name=NULL, const char** realName=NULL ) - - Loads an object from a file. - - - - - - - :param filename: File name - - - :param storage: Memory storage for dynamic structures, such as :ref:`CvSeq` or :ref:`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 realName: Optional output parameter that will contain the name of the loaded object (useful if ``name=NULL`` ) - - - -The function loads an object from a file. It provides a -simple interface to -:ref:`Read` -. 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. - - -.. index:: OpenFileStorage - -.. _OpenFileStorage: - -OpenFileStorage ---------------- - - - - - - -.. cfunction:: CvFileStorage* cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, int flags) - - Opens file storage for reading or writing data. - - - - - - - :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 :ref:`CvSeq` or :ref:`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 - - - - - - -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 -:ref:`CvFileStorage` -structure. - - -.. index:: Read - -.. _Read: - -Read ----- - - - - - - -.. cfunction:: void* cvRead( CvFileStorage* fs, CvFileNode* node, CvAttrList* attributes=NULL ) - - Decodes an object and returns a pointer to it. - - - - - - - :param fs: File storage - - - :param node: The root object node - - - :param attributes: Unused parameter - - - -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 -:ref:`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 -:ref:`OpenFileStorage` -or, if a NULL pointer was passed, in temporary -memory storage, which is released when -:ref:`ReleaseFileStorage` -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 -:ref:`Release` -. - - -.. index:: ReadByName - -.. _ReadByName: - -ReadByName ----------- - - - - - - -.. cfunction:: void* cvReadByName( CvFileStorage* fs, const CvFileNode* map, const char* name, CvAttrList* attributes=NULL ) - - Finds an object by name and decodes it. - - - - - - - :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 - - - -The function is a simple superposition of -:ref:`GetFileNodeByName` -and -:ref:`Read` -. - - -.. index:: ReadInt - -.. _ReadInt: - -ReadInt -------- - - - - - - -.. cfunction:: int cvReadInt( const CvFileNode* node, int defaultValue=0 ) - - Retrieves an integer value from a file node. - - - - - - - :param node: File node - - - :param defaultValue: The value that is returned if ``node`` is NULL - - - -The function returns an integer that is represented -by the file node. If the file node is NULL, the -``defaultValue`` -is returned (thus, it is convenient to call the function right after -:ref:`GetFileNode` -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 -result is not determined. - - -.. index:: ReadIntByName - -.. _ReadIntByName: - -ReadIntByName -------------- - - - - - - -.. cfunction:: int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, int defaultValue=0 ) - - Finds a file node and returns its value. - - - - - - - :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 defaultValue: The value that is returned if the file node is not found - - - -The function is a simple superposition of -:ref:`GetFileNodeByName` -and -:ref:`ReadInt` -. - - - -.. index:: ReadRawData - -.. _ReadRawData: - -ReadRawData ------------ - - - - - - -.. cfunction:: void cvReadRawData( const CvFileStorage* fs, const CvFileNode* src, void* dst, const char* dt) - - Reads multiple numbers. - - - - - - - :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 :ref:`WriteRawData` . - - - -The function reads elements from a file node that represents a sequence of scalars. - - -.. index:: ReadRawDataSlice - -.. _ReadRawDataSlice: - -ReadRawDataSlice ----------------- - - - - - - -.. cfunction:: void cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, int count, void* dst, const char* dt ) - - Initializes file node sequence reader. - - - - - - - :param fs: File storage - - - :param reader: The sequence reader. Initialize it with :ref:`StartReadRawData` . - - - :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 :ref:`WriteRawData` . - - - -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 -:math:`\texttt{total} \times 3` -sequence elements. As with any sequence, some parts of the file node -sequence may be skipped or read repeatedly by repositioning the reader -using -:ref:`SetSeqReaderPos` -. - - - -.. index:: ReadReal - -.. _ReadReal: - -ReadReal --------- - - - - - - -.. cfunction:: double cvReadReal( const CvFileNode* node, double defaultValue=0. ) - - Retrieves a floating-point value from a file node. - - - - - - - :param node: File node - - - :param defaultValue: The value that is returned if ``node`` is NULL - - - -The function returns a floating-point value -that is represented by the file node. If the file node is NULL, the -``defaultValue`` -is returned (thus, it is convenient to call -the function right after -:ref:`GetFileNode` -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. - - -.. index:: ReadRealByName - -.. _ReadRealByName: - -ReadRealByName --------------- - - - - - - -.. cfunction:: double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, double defaultValue=0.) - - Finds a file node and returns its value. - - - - - - - :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 defaultValue: The value that is returned if the file node is not found - - - -The function is a simple superposition of -:ref:`GetFileNodeByName` -and -:ref:`ReadReal` -. - - -.. index:: ReadString - -.. _ReadString: - -ReadString ----------- - - - - - - -.. cfunction:: const char* cvReadString( const CvFileNode* node, const char* defaultValue=NULL ) - - Retrieves a text string from a file node. - - - - - - - :param node: File node - - - :param defaultValue: The value that is returned if ``node`` is NULL - - - -The function returns a text string that is represented -by the file node. If the file node is NULL, the -``defaultValue`` -is returned (thus, it is convenient to call the function right after -:ref:`GetFileNode` -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. - - -.. index:: ReadStringByName - -.. _ReadStringByName: - -ReadStringByName ----------------- - - - - - - -.. cfunction:: const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, const char* defaultValue=NULL ) - - Finds a file node by its name and returns its value. - - - - - - - :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 defaultValue: The value that is returned if the file node is not found - - - -The function is a simple superposition of -:ref:`GetFileNodeByName` -and -:ref:`ReadString` -. - - -.. index:: RegisterType - -.. _RegisterType: - -RegisterType ------------- - - - - - - -.. cfunction:: void cvRegisterType(const CvTypeInfo* info) - - Registers a new type. - - - - - - - :param info: Type info structure - - - -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. - - -.. index:: Release - -.. _Release: - -Release -------- - - - - - - -.. cfunction:: void cvRelease( void** structPtr ) - - Releases an object. - - - - - - - :param structPtr: Double pointer to the object - - - -The function finds the type of a given object and calls -``release`` -with the double pointer. - - -.. index:: ReleaseFileStorage - -.. _ReleaseFileStorage: - -ReleaseFileStorage ------------------- - - - - - - -.. cfunction:: void cvReleaseFileStorage(CvFileStorage** fs) - - Releases file storage. - - - - - - - :param fs: Double pointer to the released 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. - - -.. index:: Save - -.. _Save: - -Save ----- - - - - - - -.. cfunction:: void cvSave( const char* filename, const void* structPtr, const char* name=NULL, const char* comment=NULL, CvAttrList attributes=cvAttrList()) - - Saves an object to a file. - - - - - - - :param filename: File name - - - :param structPtr: 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 :ref:`Write` - - - -The function saves an object to a file. It provides a simple interface to -:ref:`Write` -. - - -.. index:: StartNextStream - -.. _StartNextStream: - -StartNextStream ---------------- - - - - - - -.. cfunction:: void cvStartNextStream(CvFileStorage* fs) - - Starts the next stream. - - - - - - - :param fs: File storage - - - -The function starts the next stream in file storage. Both YAML and XML support multiple "streams." This is useful for concatenating files or for resuming the writing process. - - -.. index:: StartReadRawData - -.. _StartReadRawData: - -StartReadRawData ----------------- - - - - - - -.. cfunction:: void cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src, CvSeqReader* reader) - - Initializes the file node sequence reader. - - - - - - - :param fs: File storage - - - :param src: The file node (a sequence) to read numbers from - - - :param reader: Pointer to the sequence reader - - - -The function initializes the sequence reader to read data from a file node. The initialized reader can be then passed to -:ref:`ReadRawDataSlice` -. - - -.. index:: StartWriteStruct - -.. _StartWriteStruct: - -StartWriteStruct ----------------- - - - - - - -.. cfunction:: void cvStartWriteStruct( CvFileStorage* fs, const char* name, int struct_flags, const char* typeName=NULL, CvAttrList attributes=cvAttrList( )) - - Starts writing a new structure. - - - - - - - :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 :ref:`CvFileStorage` ), that is, its elements do not have a name. - - * **CV_NODE_MAP** the written structure is a map (see discussion of :ref:`CvFileStorage` ), that is, all its elements have names. - - - One and only one of the two above flags must be specified - - - :param 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 typeName: 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 :ref:`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 :ref:`CvTypeInfo` and :ref:`FindTypeInfo` ). - - - :param attributes: This parameter is not used in the current implementation - - - -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, -:ref:`EndWriteStruct` -should be called. The function can -be used to group some objects or to implement the -``write`` -function for a some user object (see -:ref:`CvTypeInfo` -). - - -.. index:: TypeOf - -.. _TypeOf: - -TypeOf ------- - - - - - - -.. cfunction:: CvTypeInfo* cvTypeOf( const void* structPtr ) - - Returns the type of an object. - - - - - - - :param structPtr: The object pointer - - - -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. - - -.. index:: UnregisterType - -.. _UnregisterType: - -UnregisterType --------------- - - - - - - -.. cfunction:: void cvUnregisterType( const char* typeName ) - - Unregisters the type. - - - - - - - :param typeName: Name of an unregistered 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 -:ref:`TypeOf` -or by -iterating the type list, starting from -:ref:`FirstType` -, and then calling -``cvUnregisterType(info->typeName)`` -. - - -.. index:: Write - -.. _Write: - -Write ------ - - - - - - -.. cfunction:: void cvWrite( CvFileStorage* fs, const char* name, const void* ptr, CvAttrList attributes=cvAttrList() ) - - Writes a user object. - - - - - - - :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 dicsussion below). - - - -The function writes an object to file storage. First, the appropriate type info is found using -:ref:`TypeOf` -. 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 -:ref:`WriteRawData` -): - - - - - -#. - 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: - - - - -:: - - - - #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; - } - - -.. - - -.. index:: WriteComment - -.. _WriteComment: - -WriteComment ------------- - - - - - - -.. cfunction:: void cvWriteComment( CvFileStorage* fs, const char* comment, int eolComment) - - Writes a comment. - - - - - - - :param fs: File storage - - - :param comment: The written comment, single-line or multi-line - - - :param eolComment: 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. - - - -The function writes a comment into file storage. The comments are skipped when the storage is read, so they may be used only for debugging or descriptive purposes. - - -.. index:: WriteFileNode - -.. _WriteFileNode: - -WriteFileNode -------------- - - - - - - -.. cfunction:: void cvWriteFileNode( CvFileStorage* fs, const char* new_node_name, const CvFileNode* node, int embed ) - - Writes a file node to another file storage. - - - - - - - :param fs: Destination file storage - - - :param new_file_node: New name of the file node in the destination file storage. To keep the existing name, use :ref:`cvGetFileNodeName` - - - :param node: The written node - - - :param embed: If the written node is a collection and this parameter is not zero, no extra level of hiararchy is created. Instead, all the elements of ``node`` are written into the currently written structure. Of course, map elements may be written only to a map, and sequence elements may be written only to a sequence. - - - -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. - - - -.. index:: WriteInt - -.. _WriteInt: - -WriteInt --------- - - - - - - -.. cfunction:: void cvWriteInt( CvFileStorage* fs, const char* name, int value) - - Writes an integer value. - - - - - - - :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 - - - -The function writes a single integer value (with or without a name) to the file storage. - - -.. index:: WriteRawData - -.. _WriteRawData: - -WriteRawData ------------- - - - - - - -.. cfunction:: void cvWriteRawData( CvFileStorage* fs, const void* src, int len, const char* dt ) - - Writes multiple numbers. - - - - - - - :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 that has the following format ``([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. - - - - - -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 -:ref:`WriteInt` -and -:ref:`WriteReal` -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. - - -.. index:: WriteReal - -.. _WriteReal: - -WriteReal ---------- - - - - - - -.. cfunction:: void cvWriteReal( CvFileStorage* fs, const char* name, double value ) - - Writes a floating-point value. - - - - - - - :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 - - - -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, -:math:`\pm \infty` -as +.Inf -(-.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. - - - - -:: - - - - 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 ); - } - - -.. - - -.. index:: WriteString - -.. _WriteString: - -WriteString ------------ - - - - - - -.. cfunction:: void cvWriteString( CvFileStorage* fs, const char* name, const char* str, int quote=0 ) - - Writes a text string. - - - - - - - :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). - - - -The function writes a text string to file storage. - diff --git a/doc/opencv1/c/features2d.rst b/doc/opencv1/c/features2d.rst deleted file mode 100644 index 4cd910920d..0000000000 --- a/doc/opencv1/c/features2d.rst +++ /dev/null @@ -1,10 +0,0 @@ -******************************************************* -features2d. Feature Detection and Descriptor Extraction -******************************************************* - - - -.. toctree:: - :maxdepth: 2 - - features2d_feature_detection_and_description diff --git a/doc/opencv1/c/features2d_feature_detection_and_description.rst b/doc/opencv1/c/features2d_feature_detection_and_description.rst deleted file mode 100644 index fc7a0e9cb8..0000000000 --- a/doc/opencv1/c/features2d_feature_detection_and_description.rst +++ /dev/null @@ -1,270 +0,0 @@ -Feature detection and description -================================= - -.. highlight:: c - - - - - - * **image** The image. Keypoints (corners) will be detected on this. - - - * **keypoints** Keypoints detected on the image. - - - * **threshold** Threshold on difference between intensity of center pixel and - pixels on circle around this pixel. See description of the algorithm. - - - * **nonmaxSupression** If it is true then non-maximum supression will be applied to detected corners (keypoints). - - - - -.. index:: ExtractSURF - -.. _ExtractSURF: - -ExtractSURF ------------ - - - - - - -.. cfunction:: void cvExtractSURF( const CvArr* image, const CvArr* mask, CvSeq** keypoints, CvSeq** descriptors, CvMemStorage* storage, CvSURFParams params ) - - Extracts Speeded Up Robust Features from an image. - - - - - - - :param image: The input 8-bit grayscale image - - - :param mask: The optional input 8-bit mask. The features are only found in the areas that contain more than 50 % of non-zero mask pixels - - - :param keypoints: The output parameter; double pointer to the sequence of keypoints. The sequence of CvSURFPoint structures is as follows: - - - - - :: - - - - typedef struct CvSURFPoint - { - CvPoint2D32f pt; // position of the feature within the image - int laplacian; // -1, 0 or +1. sign of the laplacian at the point. - // can be used to speedup feature comparison - // (normally features with laplacians of different - // signs can not match) - int size; // size of the feature - float dir; // orientation of the feature: 0..360 degrees - float hessian; // value of the hessian (can be used to - // approximately estimate the feature strengths; - // see also params.hessianThreshold) - } - CvSURFPoint; - - - .. - - - :param descriptors: The optional output parameter; double pointer to the sequence of descriptors. Depending on the params.extended value, each element of the sequence will be either a 64-element or a 128-element floating-point ( ``CV_32F`` ) vector. If the parameter is NULL, the descriptors are not computed - - - :param storage: Memory storage where keypoints and descriptors will be stored - - - :param params: Various algorithm parameters put to the structure CvSURFParams: - - - - - :: - - - - typedef struct CvSURFParams - { - int extended; // 0 means basic descriptors (64 elements each), - // 1 means extended descriptors (128 elements each) - double hessianThreshold; // only features with keypoint.hessian - // larger than that are extracted. - // good default value is ~300-500 (can depend on the - // average local contrast and sharpness of the image). - // user can further filter out some features based on - // their hessian values and other characteristics. - int nOctaves; // the number of octaves to be used for extraction. - // With each next octave the feature size is doubled - // (3 by default) - int nOctaveLayers; // The number of layers within each octave - // (4 by default) - } - CvSURFParams; - - CvSURFParams cvSURFParams(double hessianThreshold, int extended=0); - // returns default parameters - - - .. - - - -The function cvExtractSURF finds robust features in the image, as -described in -Bay06 -. For each feature it returns its location, size, -orientation and optionally the descriptor, basic or extended. The function -can be used for object tracking and localization, image stitching etc. - -See the -``find_obj.cpp`` -demo in OpenCV samples directory. - -.. index:: GetStarKeypoints - -.. _GetStarKeypoints: - -GetStarKeypoints ----------------- - - - - - - -.. cfunction:: CvSeq* cvGetStarKeypoints( const CvArr* image, CvMemStorage* storage, CvStarDetectorParams params=cvStarDetectorParams() ) - - Retrieves keypoints using the StarDetector algorithm. - - - - - - - :param image: The input 8-bit grayscale image - - - :param storage: Memory storage where the keypoints will be stored - - - :param params: Various algorithm parameters given to the structure CvStarDetectorParams: - - - - - :: - - - - typedef struct CvStarDetectorParams - { - int maxSize; // maximal size of the features detected. The following - // values of the parameter are supported: - // 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128 - int responseThreshold; // threshold for the approximatd laplacian, - // used to eliminate weak features - int lineThresholdProjected; // another threshold for laplacian to - // eliminate edges - int lineThresholdBinarized; // another threshold for the feature - // scale to eliminate edges - int suppressNonmaxSize; // linear size of a pixel neighborhood - // for non-maxima suppression - } - CvStarDetectorParams; - - - .. - - - -The function GetStarKeypoints extracts keypoints that are local -scale-space extremas. The scale-space is constructed by computing -approximate values of laplacians with different sigma's at each -pixel. Instead of using pyramids, a popular approach to save computing -time, all of the laplacians are computed at each pixel of the original -high-resolution image. But each approximate laplacian value is computed -in O(1) time regardless of the sigma, thanks to the use of integral -images. The algorithm is based on the paper -Agrawal08 -, but instead -of a square, hexagon or octagon it uses an 8-end star shape, hence the name, -consisting of overlapping upright and tilted squares. - -Each computed feature is represented by the following structure: - - - - -:: - - - - typedef struct CvStarKeypoint - { - CvPoint pt; // coordinates of the feature - int size; // feature size, see CvStarDetectorParams::maxSize - float response; // the approximated laplacian value at that point. - } - CvStarKeypoint; - - inline CvStarKeypoint cvStarKeypoint(CvPoint pt, int size, float response); - - -.. - -Below is the small usage sample: - - - - -:: - - - - #include "cv.h" - #include "highgui.h" - - int main(int argc, char** argv) - { - const char* filename = argc > 1 ? argv[1] : "lena.jpg"; - IplImage* img = cvLoadImage( filename, 0 ), *cimg; - CvMemStorage* storage = cvCreateMemStorage(0); - CvSeq* keypoints = 0; - int i; - - if( !img ) - return 0; - cvNamedWindow( "image", 1 ); - cvShowImage( "image", img ); - cvNamedWindow( "features", 1 ); - cimg = cvCreateImage( cvGetSize(img), 8, 3 ); - cvCvtColor( img, cimg, CV_GRAY2BGR ); - - keypoints = cvGetStarKeypoints( img, storage, cvStarDetectorParams(45) ); - - for( i = 0; i < (keypoints ? keypoints->total : 0); i++ ) - { - CvStarKeypoint kpt = *(CvStarKeypoint*)cvGetSeqElem(keypoints, i); - int r = kpt.size/2; - cvCircle( cimg, kpt.pt, r, CV_RGB(0,255,0)); - cvLine( cimg, cvPoint(kpt.pt.x + r, kpt.pt.y + r), - cvPoint(kpt.pt.x - r, kpt.pt.y - r), CV_RGB(0,255,0)); - cvLine( cimg, cvPoint(kpt.pt.x - r, kpt.pt.y + r), - cvPoint(kpt.pt.x + r, kpt.pt.y - r), CV_RGB(0,255,0)); - } - cvShowImage( "features", cimg ); - cvWaitKey(); - } - - -.. - diff --git a/doc/opencv1/c/highgui.rst b/doc/opencv1/c/highgui.rst deleted file mode 100644 index 06417b3cf0..0000000000 --- a/doc/opencv1/c/highgui.rst +++ /dev/null @@ -1,39 +0,0 @@ -************************************* -highgui. High-level GUI and Media I/O -************************************* - - -While OpenCV was designed for use in full-scale -applications and can be used within functionally rich UI frameworks (such as Qt, WinForms or Cocoa) or without any UI at all, sometimes there is a need to try some functionality quickly and visualize the results. This is what the HighGUI module has been designed for. - -It provides easy interface to: - - - - -* - create and manipulate windows that can display images and "remember" their content (no need to handle repaint events from OS) - - - -* - add trackbars to the windows, handle simple mouse events as well as keyboard commmands - - - -* - read and write images to/from disk or memory. - - - -* - read video from camera or file and write video to a file. - - - -.. toctree:: - :maxdepth: 2 - - highgui_user_interface - highgui_reading_and_writing_images_and_video - highgui_qt_new_functions diff --git a/doc/opencv1/c/highgui_qt_new_functions.rst b/doc/opencv1/c/highgui_qt_new_functions.rst deleted file mode 100644 index 70b4ba5dfa..0000000000 --- a/doc/opencv1/c/highgui_qt_new_functions.rst +++ /dev/null @@ -1,674 +0,0 @@ -Qt new functions -================ - -.. highlight:: c - - - - -.. image:: ../pics/qtgui.png - - - -This figure explains the new functionalities implemented with Qt GUI. As we can see, the new GUI provides a statusbar, a toolbar, and a control panel. The control panel can have trackbars and buttonbars attached to it. - - - - -* - To attach a trackbar, the window - _ - name parameter must be NULL. - - - -* - To attach a buttonbar, a button must be created. - If the last bar attached to the control panel is a buttonbar, the new button is added on the right of the last button. - If the last bar attached to the control panel is a trackbar, or the control panel is empty, a new buttonbar is created. Then a new button is attached to it. - - -The following code is an example used to generate the figure. - - - -:: - - - - int main(int argc, char *argv[]) - int value = 50; - int value2 = 0; - - cvNamedWindow("main1",CV_WINDOW_NORMAL); - cvNamedWindow("main2",CV_WINDOW_AUTOSIZE | CV_GUI_NORMAL); - - cvCreateTrackbar( "track1", "main1", &value, 255, NULL);//OK tested - char* nameb1 = "button1"; - char* nameb2 = "button2"; - cvCreateButton(nameb1,callbackButton,nameb1,CV_CHECKBOX,1); - - cvCreateButton(nameb2,callbackButton,nameb2,CV_CHECKBOX,0); - cvCreateTrackbar( "track2", NULL, &value2, 255, NULL); - cvCreateButton("button5",callbackButton1,NULL,CV_RADIOBOX,0); - cvCreateButton("button6",callbackButton2,NULL,CV_RADIOBOX,1); - - cvSetMouseCallback( "main2",on_mouse,NULL ); - - IplImage* img1 = cvLoadImage("files/flower.jpg"); - IplImage* img2 = cvCreateImage(cvGetSize(img1),8,3); - CvCapture* video = cvCaptureFromFile("files/hockey.avi"); - IplImage* img3 = cvCreateImage(cvGetSize(cvQueryFrame(video)),8,3); - - while(cvWaitKey(33) != 27) - { - cvAddS(img1,cvScalarAll(value),img2); - cvAddS(cvQueryFrame(video),cvScalarAll(value2),img3); - cvShowImage("main1",img2); - cvShowImage("main2",img3); - } - - cvDestroyAllWindows(); - cvReleaseImage(&img1); - cvReleaseImage(&img2); - cvReleaseImage(&img3); - cvReleaseCapture(&video); - return 0; - } - - -.. - - -.. index:: SetWindowProperty - -.. _SetWindowProperty: - -SetWindowProperty ------------------ - - - - - - -.. cfunction:: void cvSetWindowProperty(const char* name, int prop_id, double prop_value) - - Change the parameters of the window dynamically. - - - - - - - :param name: Name of the window. - - - :param prop_id: Window's property to edit. The operation flags: - - - - * **CV_WND_PROP_FULLSCREEN** Change if the window is fullscreen ( ``CV_WINDOW_NORMAL`` or ``CV_WINDOW_FULLSCREEN`` ). - - - * **CV_WND_PROP_AUTOSIZE** Change if the user can resize the window (texttt {CV\_WINDOW\_NORMAL} or ``CV_WINDOW_AUTOSIZE`` ). - - - * **CV_WND_PROP_ASPECTRATIO** Change if the image's aspect ratio is preserved (texttt {CV\_WINDOW\_FREERATIO} or ``CV_WINDOW_KEEPRATIO`` ). - - - - - - :param prop_value: New value of the Window's property. The operation flags: - - - - * **CV_WINDOW_NORMAL** Change the window in normal size, or allows the user to resize the window. - - - * **CV_WINDOW_AUTOSIZE** The user cannot resize the window, the size is constrainted by the image displayed. - - - * **CV_WINDOW_FULLSCREEN** Change the window to fullscreen. - - - * **CV_WINDOW_FREERATIO** The image expends as much as it can (no ratio constraint) - - - * **CV_WINDOW_KEEPRATIO** The ration image is respected. - - - - - - -The function -`` cvSetWindowProperty`` -allows to change the window's properties. - - - - - -.. index:: GetWindowProperty - -.. _GetWindowProperty: - -GetWindowProperty ------------------ - - - - - - -.. cfunction:: void cvGetWindowProperty(const char* name, int prop_id) - - Get the parameters of the window. - - - - - - - :param name: Name of the window. - - - :param prop_id: Window's property to retrive. The operation flags: - - - - * **CV_WND_PROP_FULLSCREEN** Change if the window is fullscreen ( ``CV_WINDOW_NORMAL`` or ``CV_WINDOW_FULLSCREEN`` ). - - - * **CV_WND_PROP_AUTOSIZE** Change if the user can resize the window (texttt {CV\_WINDOW\_NORMAL} or ``CV_WINDOW_AUTOSIZE`` ). - - - * **CV_WND_PROP_ASPECTRATIO** Change if the image's aspect ratio is preserved (texttt {CV\_WINDOW\_FREERATIO} or ``CV_WINDOW_KEEPRATIO`` ). - - - - - - -See -:ref:`SetWindowProperty` -to know the meaning of the returned values. - -The function -`` cvGetWindowProperty`` -return window's properties. - - - -.. index:: FontQt - -.. _FontQt: - -FontQt ------- - - - - -:ref:`addText` - - -.. cfunction:: CvFont cvFontQt(const char* nameFont, int pointSize = -1, CvScalar color = cvScalarAll(0), int weight = CV_FONT_NORMAL, int style = CV_STYLE_NORMAL, int spacing = 0) - - Create the font to be used to draw text on an image (with ). - - - - - - - :param nameFont: Name of the font. The name should match the name of a system font (such as ``Times''). If the font is not found, a default one will be used. - - - :param pointSize: Size of the font. If not specified, equal zero or negative, the point size of the font is set to a system-dependent default value. Generally, this is 12 points. - - - :param color: Color of the font in BGRA -- A = 255 is fully transparent. Use the macro CV _ RGB for simplicity. - - - :param weight: The operation flags: - - - - * **CV_FONT_LIGHT** Weight of 25 - - - * **CV_FONT_NORMAL** Weight of 50 - - - * **CV_FONT_DEMIBOLD** Weight of 63 - - - * **CV_FONT_BOLD** Weight of 75 - - - * **CV_FONT_BLACK** Weight of 87 - - You can also specify a positive integer for more control. - - - - - :param style: The operation flags: - - - - * **CV_STYLE_NORMAL** Font is normal - - - * **CV_STYLE_ITALIC** Font is in italic - - - * **CV_STYLE_OBLIQUE** Font is oblique - - - - - - :param spacing: Spacing between characters. Can be negative or positive - - - -The function -``cvFontQt`` -creates a CvFont object to be used with -:ref:`addText` -. This CvFont is not compatible with cvPutText. - -A basic usage of this function is: - - - -:: - - - - CvFont font = cvFontQt(''Times''); - cvAddText( img1, ``Hello World !'', cvPoint(50,50), font); - - -.. - - -.. index:: AddText - -.. _AddText: - -AddText -------- - - - - - - -.. cfunction:: void cvAddText(const CvArr* img, const char* text, CvPoint location, CvFont *font) - - Create the font to be used to draw text on an image - - - - - - :param img: Image where the text should be drawn - - - :param text: Text to write on the image - - - :param location: Point(x,y) where the text should start on the image - - - :param font: Font to use to draw the text - - - -The function -``cvAddText`` -draw -*text* -on the image -*img* -using a specific font -*font* -(see example -:ref:`FontQt` -) - - - - -.. index:: DisplayOverlay - -.. _DisplayOverlay: - -DisplayOverlay --------------- - - - - - - -.. cfunction:: void cvDisplayOverlay(const char* name, const char* text, int delay) - - Display text on the window's image as an overlay for delay milliseconds. This is not editing the image's data. The text is display on the top of the image. - - - - - - :param name: Name of the window - - - :param text: Overlay text to write on the window's image - - - :param delay: Delay to display the overlay text. If this function is called before the previous overlay text time out, the timer is restarted and the text updated. . If this value is zero, the text never disapers. - - - -The function -``cvDisplayOverlay`` -aims at displaying useful information/tips on the window for a certain amount of time -*delay* -. This information is display on the top of the window. - - - - -.. index:: DisplayStatusBar - -.. _DisplayStatusBar: - -DisplayStatusBar ----------------- - - - - - - -.. cfunction:: void cvDisplayStatusBar(const char* name, const char* text, int delayms) - - Display text on the window's statusbar as for delay milliseconds. - - - - - - :param name: Name of the window - - - :param text: Text to write on the window's statusbar - - - :param delay: Delay to display the text. If this function is called before the previous text time out, the timer is restarted and the text updated. If this value is zero, the text never disapers. - - - -The function -``cvDisplayOverlay`` -aims at displaying useful information/tips on the window for a certain amount of time -*delay* -. This information is displayed on the window's statubar (the window must be created with -``CV_GUI_EXPANDED`` -flags). - - - - - -.. index:: CreateOpenGLCallback - -.. _CreateOpenGLCallback: - -CreateOpenGLCallback --------------------- - - - - -*_* - - -.. cfunction:: void cvCreateOpenGLCallback( const char* window_name, CvOpenGLCallback callbackOpenGL, void* userdata CV_DEFAULT(NULL), double angle CV_DEFAULT(-1), double zmin CV_DEFAULT(-1), double zmax CV_DEFAULT(-1) - - Create a callback function called to draw OpenGL on top the the image display by windowname. - - - - - - :param window_name: Name of the window - - - :param callbackOpenGL: - Pointer to the function to be called every frame. - This function should be prototyped as ``void Foo(*void);`` . - - - :param userdata: pointer passed to the callback function. *(Optional)* - - - :param angle: Specifies the field of view angle, in degrees, in the y direction.. *(Optional - Default 45 degree)* - - - :param zmin: Specifies the distance from the viewer to the near clipping plane (always positive). *(Optional - Default 0.01)* - - - :param zmax: Specifies the distance from the viewer to the far clipping plane (always positive). *(Optional - Default 1000)* - - - -The function -``cvCreateOpenGLCallback`` -can be used to draw 3D data on the window. An example of callback could be: - - - -:: - - - - void on_opengl(void* param) - { - //draw scene here - glLoadIdentity(); - - glTranslated(0.0, 0.0, -1.0); - - glRotatef( 55, 1, 0, 0 ); - glRotatef( 45, 0, 1, 0 ); - glRotatef( 0, 0, 0, 1 ); - - static const int coords[6][4][3] = { - { { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } }, - { { +1, +1, -1 }, { -1, +1, -1 }, { -1, +1, +1 }, { +1, +1, +1 } }, - { { +1, -1, +1 }, { +1, -1, -1 }, { +1, +1, -1 }, { +1, +1, +1 } }, - { { -1, -1, -1 }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, -1 } }, - { { +1, -1, +1 }, { -1, -1, +1 }, { -1, -1, -1 }, { +1, -1, -1 } }, - { { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } } - }; - - for (int i = 0; i < 6; ++i) { - glColor3ub( i*20, 100+i*10, i*42 ); - glBegin(GL_QUADS); - for (int j = 0; j < 4; ++j) { - glVertex3d(0.2 * coords[i][j][0], 0.2 * coords[i][j][1], 0.2 * coords[i][j][2]); - } - glEnd(); - } - } - - -.. - - - - -:: - - - - CV_EXTERN_C_FUNCPTR( *CvOpenGLCallback)(void* userdata)); - - -.. - - -.. index:: SaveWindowParameters - -.. _SaveWindowParameters: - -SaveWindowParameters --------------------- - - - - -*_* - - -.. cfunction:: void cvSaveWindowParameters(const char* name) - - Save parameters of the window windowname. - - - - - - :param name: Name of the window - - - -The function -``cvSaveWindowParameters`` -saves size, location, flags, trackbars' value, zoom and panning location of the window -*window_name* - -.. index:: LoadWindowParameters - -.. _LoadWindowParameters: - -LoadWindowParameters --------------------- - - - - -*_* - - -.. cfunction:: void cvLoadWindowParameters(const char* name) - - Load parameters of the window windowname. - - - - - - :param name: Name of the window - - - -The function -``cvLoadWindowParameters`` -load size, location, flags, trackbars' value, zoom and panning location of the window -*window_name* - -.. index:: CreateButton - -.. _CreateButton: - -CreateButton ------------- - - - - -*_* - - -.. cfunction:: cvCreateButton( const char* button_name CV_DEFAULT(NULL),CvButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL) , int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0) - - Create a callback function called to draw OpenGL on top the the image display by windowname. - - - - - - :param button_name: Name of the button *( if NULL, the name will be "button ")* - - - :param on_change: - Pointer to the function to be called every time the button changed its state. - This function should be prototyped as ``void Foo(int state,*void);`` . *state* is the current state of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button. - - - :param userdata: pointer passed to the callback function. *(Optional)* - - - -The -``button_type`` -parameter can be : -*(Optional -- Will be a push button by default.) - - * **CV_PUSH_BUTTON** The button will be a push button. - - * **CV_CHECKBOX** The button will be a checkbox button. - - * **CV_RADIOBOX** The button will be a radiobox button. The radiobox on the same buttonbar (same line) are exclusive; one on can be select at the time. - - * - - - - * **initial_button_state** Default state of the button. Use for checkbox and radiobox, its value could be 0 or 1. *(Optional)* - - - -The function -``cvCreateButton`` -attach button to the control panel. Each button is added to a buttonbar on the right of the last button. -A new buttonbar is create if nothing was attached to the control panel before, or if the last element attached to the control panel was a trackbar. - -Here are various example of -``cvCreateButton`` -function call: - - - -:: - - - - cvCreateButton(NULL,callbackButton);//create a push button "button 0", that will call callbackButton. - cvCreateButton("button2",callbackButton,NULL,CV_CHECKBOX,0); - cvCreateButton("button3",callbackButton,&value); - cvCreateButton("button5",callbackButton1,NULL,CV_RADIOBOX); - cvCreateButton("button6",callbackButton2,NULL,CV_PUSH_BUTTON,1); - - -.. - - - - -:: - - - - CV_EXTERN_C_FUNCPTR( *CvButtonCallback)(int state, void* userdata)); - - -.. - diff --git a/doc/opencv1/c/highgui_reading_and_writing_images_and_video.rst b/doc/opencv1/c/highgui_reading_and_writing_images_and_video.rst deleted file mode 100644 index 81af542833..0000000000 --- a/doc/opencv1/c/highgui_reading_and_writing_images_and_video.rst +++ /dev/null @@ -1,726 +0,0 @@ -Reading and Writing Images and Video -==================================== - -.. highlight:: c - - - -.. index:: LoadImage - -.. _LoadImage: - -LoadImage ---------- - - - - - - -.. cfunction:: IplImage* cvLoadImage( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR ) - - Loads an image from a file as an IplImage. - - - - - - - :param filename: Name of file to be loaded. - - - :param iscolor: Specific color type of the loaded image: - - * **CV_LOAD_IMAGE_COLOR** the loaded image is forced to be a 3-channel color image - - * **CV_LOAD_IMAGE_GRAYSCALE** the loaded image is forced to be grayscale - - * **CV_LOAD_IMAGE_UNCHANGED** the loaded image will be loaded as is. - - - - - -The function -``cvLoadImage`` -loads an image from the specified file and returns the pointer to the loaded image. Currently the following file formats are supported: - - - - -* - Windows bitmaps - BMP, DIB - - -* - JPEG files - JPEG, JPG, JPE - - -* - Portable Network Graphics - PNG - - -* - Portable image format - PBM, PGM, PPM - - -* - Sun rasters - SR, RAS - - -* - TIFF files - TIFF, TIF - - -Note that in the current implementation the alpha channel, if any, is stripped from the output image, e.g. 4-channel RGBA image will be loaded as RGB. - - -.. index:: LoadImageM - -.. _LoadImageM: - -LoadImageM ----------- - - - - - - -.. cfunction:: CvMat* cvLoadImageM( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR ) - - Loads an image from a file as a CvMat. - - - - - - - :param filename: Name of file to be loaded. - - - :param iscolor: Specific color type of the loaded image: - - * **CV_LOAD_IMAGE_COLOR** the loaded image is forced to be a 3-channel color image - - * **CV_LOAD_IMAGE_GRAYSCALE** the loaded image is forced to be grayscale - - * **CV_LOAD_IMAGE_UNCHANGED** the loaded image will be loaded as is. - - - - - -The function -``cvLoadImageM`` -loads an image from the specified file and returns the pointer to the loaded image. -urrently the following file formats are supported: - - - - -* - Windows bitmaps - BMP, DIB - - -* - JPEG files - JPEG, JPG, JPE - - -* - Portable Network Graphics - PNG - - -* - Portable image format - PBM, PGM, PPM - - -* - Sun rasters - SR, RAS - - -* - TIFF files - TIFF, TIF - - -Note that in the current implementation the alpha channel, if any, is stripped from the output image, e.g. 4-channel RGBA image will be loaded as RGB. - - -.. index:: SaveImage - -.. _SaveImage: - -SaveImage ---------- - - - - - - -.. cfunction:: int cvSaveImage( const char* filename, const CvArr* image ) - - Saves an image to a specified file. - - - - - - - :param filename: Name of the file. - - - :param image: Image to be saved. - - - -The function -``cvSaveImage`` -saves the image to the specified file. The image format is chosen based on the -``filename`` -extension, see -:ref:`LoadImage` -. Only 8-bit single-channel or 3-channel (with 'BGR' channel order) images can be saved using this function. If the format, depth or channel order is different, use -``cvCvtScale`` -and -``cvCvtColor`` -to convert it before saving, or use universal -``cvSave`` -to save the image to XML or YAML format. - - - -.. index:: CvCapture - -.. _CvCapture: - -CvCapture ---------- - - - -.. ctype:: CvCapture - - - -Video capturing structure. - - - -.. cfunction:: typedef struct CvCapture CvCapture - - - - -The structure -``CvCapture`` -does not have a public interface and is used only as a parameter for video capturing functions. - - -.. index:: CaptureFromCAM - -.. _CaptureFromCAM: - -CaptureFromCAM --------------- - - - - - - -.. cfunction:: CvCapture* cvCaptureFromCAM( int index ) - - Initializes capturing a video from a camera. - - - - - - - :param index: Index of the camera to be used. If there is only one camera or it does not matter what camera is used -1 may be passed. - - - -The function -``cvCaptureFromCAM`` -allocates and initializes the CvCapture structure for reading a video stream from the camera. Currently two camera interfaces can be used on Windows: Video for Windows (VFW) and Matrox Imaging Library (MIL); and two on Linux: V4L and FireWire (IEEE1394). - -To release the structure, use -:ref:`ReleaseCapture` -. - - - -.. index:: CaptureFromFile - -.. _CaptureFromFile: - -CaptureFromFile ---------------- - - - - - - -.. cfunction:: CvCapture* cvCaptureFromFile( const char* filename ) - - Initializes capturing a video from a file. - - - - - - - :param filename: Name of the video file. - - - -The function -``cvCaptureFromFile`` -allocates and initializes the CvCapture structure for reading the video stream from the specified file. Which codecs and file formats are supported depends on the back end library. On Windows HighGui uses Video for Windows (VfW), on Linux ffmpeg is used and on Mac OS X the back end is QuickTime. See VideoCodecs for some discussion on what to expect and how to prepare your video files. - -After the allocated structure is not used any more it should be released by the -:ref:`ReleaseCapture` -function. - - -.. index:: GetCaptureProperty - -.. _GetCaptureProperty: - -GetCaptureProperty ------------------- - - - - - - -.. cfunction:: double cvGetCaptureProperty( CvCapture* capture, int property_id ) - - Gets video capturing properties. - - - - - - - :param capture: video capturing structure. - - - :param property_id: Property identifier. Can be one of the following: - - - - - * **CV_CAP_PROP_POS_MSEC** Film current position in milliseconds or video capture timestamp - - - * **CV_CAP_PROP_POS_FRAMES** 0-based index of the frame to be decoded/captured next - - - * **CV_CAP_PROP_POS_AVI_RATIO** Relative position of the video file (0 - start of the film, 1 - end of the film) - - - * **CV_CAP_PROP_FRAME_WIDTH** Width of the frames in the video stream - - - * **CV_CAP_PROP_FRAME_HEIGHT** Height of the frames in the video stream - - - * **CV_CAP_PROP_FPS** Frame rate - - - * **CV_CAP_PROP_FOURCC** 4-character code of codec - - - * **CV_CAP_PROP_FRAME_COUNT** Number of frames in the video file - - - * **CV_CAP_PROP_FORMAT** The format of the Mat objects returned by retrieve() - - - * **CV_CAP_PROP_MODE** A backend-specific value indicating the current capture mode - - - * **CV_CAP_PROP_BRIGHTNESS** Brightness of the image (only for cameras) - - - * **CV_CAP_PROP_CONTRAST** Contrast of the image (only for cameras) - - - * **CV_CAP_PROP_SATURATION** Saturation of the image (only for cameras) - - - * **CV_CAP_PROP_HUE** Hue of the image (only for cameras) - - - * **CV_CAP_PROP_GAIN** Gain of the image (only for cameras) - - - * **CV_CAP_PROP_EXPOSURE** Exposure (only for cameras) - - - * **CV_CAP_PROP_CONVERT_RGB** Boolean flags indicating whether images should be converted to RGB - - - * **CV_CAP_PROP_WHITE_BALANCE** Currently unsupported - - - * **CV_CAP_PROP_RECTIFICATION** TOWRITE (note: only supported by DC1394 v 2.x backend currently) - - - - - -The function -``cvGetCaptureProperty`` -retrieves the specified property of the camera or video file. - - -.. index:: GrabFrame - -.. _GrabFrame: - -GrabFrame ---------- - - - - - - -.. cfunction:: int cvGrabFrame( CvCapture* capture ) - - Grabs the frame from a camera or file. - - - - - - - :param capture: video capturing structure. - - - -The function -``cvGrabFrame`` -grabs the frame from a camera or file. The grabbed frame is stored internally. The purpose of this function is to grab the frame -*quickly* -so that syncronization can occur if it has to read from several cameras simultaneously. The grabbed frames are not exposed because they may be stored in a compressed format (as defined by the camera/driver). To retrieve the grabbed frame, -:ref:`RetrieveFrame` -should be used. - - - -.. index:: QueryFrame - -.. _QueryFrame: - -QueryFrame ----------- - - - - - - -.. cfunction:: IplImage* cvQueryFrame( CvCapture* capture ) - - Grabs and returns a frame from a camera or file. - - - - - - - :param capture: video capturing structure. - - - -The function -``cvQueryFrame`` -grabs a frame from a camera or video file, decompresses it and returns it. This function is just a combination of -:ref:`GrabFrame` -and -:ref:`RetrieveFrame` -, but in one call. The returned image should not be released or modified by the user. In the event of an error, the return value may be NULL. - - -.. index:: ReleaseCapture - -.. _ReleaseCapture: - -ReleaseCapture --------------- - - - - - - -.. cfunction:: void cvReleaseCapture( CvCapture** capture ) - - Releases the CvCapture structure. - - - - - - - :param capture: Pointer to video the capturing structure. - - - -The function -``cvReleaseCapture`` -releases the CvCapture structure allocated by -:ref:`CaptureFromFile` -or -:ref:`CaptureFromCAM` -. - -.. index:: RetrieveFrame - -.. _RetrieveFrame: - -RetrieveFrame -------------- - - - - - - -.. cfunction:: IplImage* cvRetrieveFrame( CvCapture* capture ) - - Gets the image grabbed with cvGrabFrame. - - - - - - - :param capture: video capturing structure. - - - -The function -``cvRetrieveFrame`` -returns the pointer to the image grabbed with the -:ref:`GrabFrame` -function. The returned image should not be released or modified by the user. In the event of an error, the return value may be NULL. - - - -.. index:: SetCaptureProperty - -.. _SetCaptureProperty: - -SetCaptureProperty ------------------- - - - - - - -.. cfunction:: int cvSetCaptureProperty( CvCapture* capture, int property_id, double value ) - - Sets video capturing properties. - - - - - - - :param capture: video capturing structure. - - - :param property_id: property identifier. Can be one of the following: - - - - - * **CV_CAP_PROP_POS_MSEC** Film current position in milliseconds or video capture timestamp - - - * **CV_CAP_PROP_POS_FRAMES** 0-based index of the frame to be decoded/captured next - - - * **CV_CAP_PROP_POS_AVI_RATIO** Relative position of the video file (0 - start of the film, 1 - end of the film) - - - * **CV_CAP_PROP_FRAME_WIDTH** Width of the frames in the video stream - - - * **CV_CAP_PROP_FRAME_HEIGHT** Height of the frames in the video stream - - - * **CV_CAP_PROP_FPS** Frame rate - - - * **CV_CAP_PROP_FOURCC** 4-character code of codec - - - * **CV_CAP_PROP_FRAME_COUNT** Number of frames in the video file - - - * **CV_CAP_PROP_FORMAT** The format of the Mat objects returned by retrieve() - - - * **CV_CAP_PROP_MODE** A backend-specific value indicating the current capture mode - - - * **CV_CAP_PROP_BRIGHTNESS** Brightness of the image (only for cameras) - - - * **CV_CAP_PROP_CONTRAST** Contrast of the image (only for cameras) - - - * **CV_CAP_PROP_SATURATION** Saturation of the image (only for cameras) - - - * **CV_CAP_PROP_HUE** Hue of the image (only for cameras) - - - * **CV_CAP_PROP_GAIN** Gain of the image (only for cameras) - - - * **CV_CAP_PROP_EXPOSURE** Exposure (only for cameras) - - - * **CV_CAP_PROP_CONVERT_RGB** Boolean flags indicating whether images should be converted to RGB - - - * **CV_CAP_PROP_WHITE_BALANCE** Currently unsupported - - - * **CV_CAP_PROP_RECTIFICATION** TOWRITE (note: only supported by DC1394 v 2.x backend currently) - - - - - :param value: value of the property. - - - -The function -``cvSetCaptureProperty`` -sets the specified property of video capturing. Currently the function supports only video files: -``CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES, CV_CAP_PROP_POS_AVI_RATIO`` -. - -NB This function currently does nothing when using the latest CVS download on linux with FFMPEG (the function contents are hidden if 0 is used and returned). - - - -.. index:: CreateVideoWriter - -.. _CreateVideoWriter: - -CreateVideoWriter ------------------ - - - - - - -.. cfunction:: typedef struct CvVideoWriter CvVideoWriter CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, double fps, CvSize frame_size, int is_color=1 ) - - Creates the video file writer. - - - - - - - :param filename: Name of the output video file. - - - :param fourcc: 4-character code of codec used to compress the frames. For example, ``CV_FOURCC('P','I','M,'1')`` is a MPEG-1 codec, ``CV_FOURCC('M','J','P','G')`` is a motion-jpeg codec etc. - Under Win32 it is possible to pass -1 in order to choose compression method and additional compression parameters from dialog. Under Win32 if 0 is passed while using an avi filename it will create a video writer that creates an uncompressed avi file. - - - :param fps: Framerate of the created video stream. - - - :param frame_size: Size of the video frames. - - - :param is_color: If it is not zero, the encoder will expect and encode color frames, otherwise it will work with grayscale frames (the flag is currently supported on Windows only). - - - -The function -``cvCreateVideoWriter`` -creates the video writer structure. - -Which codecs and file formats are supported depends on the back end library. On Windows HighGui uses Video for Windows (VfW), on Linux ffmpeg is used and on Mac OS X the back end is QuickTime. See VideoCodecs for some discussion on what to expect. - - - -.. index:: ReleaseVideoWriter - -.. _ReleaseVideoWriter: - -ReleaseVideoWriter ------------------- - - - - - - -.. cfunction:: void cvReleaseVideoWriter( CvVideoWriter** writer ) - - Releases the AVI writer. - - - - - - - :param writer: Pointer to the video file writer structure. - - - -The function -``cvReleaseVideoWriter`` -finishes writing to the video file and releases the structure. - -.. index:: WriteFrame - -.. _WriteFrame: - -WriteFrame ----------- - - - - - - -.. cfunction:: int cvWriteFrame( CvVideoWriter* writer, const IplImage* image ) - - Writes a frame to a video file. - - - - - - - :param writer: Video writer structure - - - :param image: The written frame - - - -The function -``cvWriteFrame`` -writes/appends one frame to a video file. - diff --git a/doc/opencv1/c/highgui_user_interface.rst b/doc/opencv1/c/highgui_user_interface.rst deleted file mode 100644 index 13a83463b3..0000000000 --- a/doc/opencv1/c/highgui_user_interface.rst +++ /dev/null @@ -1,728 +0,0 @@ -User Interface -============== - -.. highlight:: c - - - -.. index:: ConvertImage - -.. _ConvertImage: - -ConvertImage ------------- - - - - - - -.. cfunction:: void cvConvertImage( const CvArr* src, CvArr* dst, int flags=0 ) - - Converts one image to another with an optional vertical flip. - - - - - - - :param src: Source image. - - - :param dst: Destination image. Must be single-channel or 3-channel 8-bit image. - - - :param flags: The operation flags: - - * **CV_CVTIMG_FLIP** Flips the image vertically - - * **CV_CVTIMG_SWAP_RB** Swaps the red and blue channels. In OpenCV color images have ``BGR`` channel order, however on some systems the order needs to be reversed before displaying the image ( :ref:`ShowImage` does this automatically). - - - - - -The function -``cvConvertImage`` -converts one image to another and flips the result vertically if desired. The function is used by -:ref:`ShowImage` -. - - -.. index:: CreateTrackbar - -.. _CreateTrackbar: - -CreateTrackbar --------------- - - - - - - -.. cfunction:: int cvCreateTrackbar( const char* trackbarName, const char* windowName, int* value, int count, CvTrackbarCallback onChange ) - - Creates a trackbar and attaches it to the specified window - - - - - - - :param trackbarName: Name of the created trackbar. - - - :param windowName: Name of the window which will be used as a parent for created trackbar. - - - :param value: Pointer to an integer variable, whose value will reflect the position of the slider. Upon creation, the slider position is defined by this variable. - - - :param count: Maximal position of the slider. Minimal position is always 0. - - - :param onChange: - Pointer to the function to be called every time the slider changes position. - This function should be prototyped as ``void Foo(int);`` Can be NULL if callback is not required. - - - -The function -``cvCreateTrackbar`` -creates a trackbar (a.k.a. slider or range control) with the specified name and range, assigns a variable to be syncronized with trackbar position and specifies a callback function to be called on trackbar position change. The created trackbar is displayed on the top of the given window. -\ -\ -**[Qt Backend Only]** -qt-specific details: - - - - * **windowName** Name of the window which will be used as a parent for created trackbar. Can be NULL if the trackbar should be attached to the control panel. - - - -The created trackbar is displayed at the bottom of the given window if -*windowName* -is correctly provided, or displayed on the control panel if -*windowName* -is NULL. - -By clicking on the label of each trackbar, it is possible to edit the trackbar's value manually for a more accurate control of it. - - - - -:: - - - - CV_EXTERN_C_FUNCPTR( void (*CvTrackbarCallback)(int pos) ); - - -.. - - -.. index:: DestroyAllWindows - -.. _DestroyAllWindows: - -DestroyAllWindows ------------------ - - - - - - -.. cfunction:: void cvDestroyAllWindows(void) - - Destroys all of the HighGUI windows. - - - -The function -``cvDestroyAllWindows`` -destroys all of the opened HighGUI windows. - - -.. index:: DestroyWindow - -.. _DestroyWindow: - -DestroyWindow -------------- - - - - - - -.. cfunction:: void cvDestroyWindow( const char* name ) - - Destroys a window. - - - - - - - :param name: Name of the window to be destroyed. - - - -The function -``cvDestroyWindow`` -destroys the window with the given name. - - -.. index:: GetTrackbarPos - -.. _GetTrackbarPos: - -GetTrackbarPos --------------- - - - - - - -.. cfunction:: int cvGetTrackbarPos( const char* trackbarName, const char* windowName ) - - Returns the trackbar position. - - - - - - - :param trackbarName: Name of the trackbar. - - - :param windowName: Name of the window which is the parent of the trackbar. - - - -The function -``cvGetTrackbarPos`` -returns the current position of the specified trackbar. -\ -\ -**[Qt Backend Only]** -qt-specific details: - - - - * **windowName** Name of the window which is the parent of the trackbar. Can be NULL if the trackbar is attached to the control panel. - - - - -.. index:: GetWindowHandle - -.. _GetWindowHandle: - -GetWindowHandle ---------------- - - - - - - -.. cfunction:: void* cvGetWindowHandle( const char* name ) - - Gets the window's handle by its name. - - - - - - - :param name: Name of the window - - . - - -The function -``cvGetWindowHandle`` -returns the native window handle (HWND in case of Win32 and GtkWidget in case of GTK+). -\ -\ -**[Qt Backend Only]** -qt-specific details: -The function -``cvGetWindowHandle`` -returns the native window handle inheriting from the Qt class QWidget. - - -.. index:: GetWindowName - -.. _GetWindowName: - -GetWindowName -------------- - - - - - - -.. cfunction:: const char* cvGetWindowName( void* windowHandle ) - - Gets the window's name by its handle. - - - - - - - :param windowHandle: Handle of the window. - - - -The function -``cvGetWindowName`` -returns the name of the window given its native handle (HWND in case of Win32 and GtkWidget in case of GTK+). -\ -\ -**[Qt Backend Only]** -qt-specific details: -The function -``cvGetWindowName`` -returns the name of the window given its native handle (QWidget). - - -.. index:: InitSystem - -.. _InitSystem: - -InitSystem ----------- - - - - - - -.. cfunction:: int cvInitSystem( int argc, char** argv ) - - Initializes HighGUI. - - - - - - - :param argc: Number of command line arguments - - - :param argv: Array of command line arguments - - - -The function -``cvInitSystem`` -initializes HighGUI. If it wasn't -called explicitly by the user before the first window was created, it is -called implicitly then with -``argc=0`` -, -``argv=NULL`` -. Under -Win32 there is no need to call it explicitly. Under X Window the arguments -may be used to customize a look of HighGUI windows and controls. -\ -\ -**[Qt Backend Only]** -qt-specific details: -The function -``cvInitSystem`` -is automatically called at the first cvNamedWindow call. - - -.. index:: MoveWindow - -.. _MoveWindow: - -MoveWindow ----------- - - - - - - -.. cfunction:: void cvMoveWindow( const char* name, int x, int y ) - - Sets the position of the window. - - - - - - - :param name: Name of the window to be moved. - - - :param x: New x coordinate of the top-left corner - - - :param y: New y coordinate of the top-left corner - - - -The function -``cvMoveWindow`` -changes the position of the window. - - -.. index:: NamedWindow - -.. _NamedWindow: - -NamedWindow ------------ - - - - - - -.. cfunction:: int cvNamedWindow( const char* name, int flags ) - - Creates a window. - - - - - - - :param name: Name of the window in the window caption that may be used as a window identifier. - - - :param flags: Flags of the window. Currently the only supported flag is ``CV_WINDOW_AUTOSIZE`` . If this is set, window size is automatically adjusted to fit the displayed image (see :ref:`ShowImage` ), and the user can not change the window size manually. - - - -The function -``cvNamedWindow`` -creates a window which can be used as a placeholder for images and trackbars. Created windows are referred to by their names. - -If a window with the same name already exists, the function does nothing. -\ -\ -**[Qt Backend Only]** -qt-specific details: - - - - * **flags** Flags of the window. Currently the supported flags are: - - - * **CV_WINDOW_NORMAL or CV_WINDOW_AUTOSIZE:** ``CV_WINDOW_NORMAL`` let the user resize the window, whereas ``CV_WINDOW_AUTOSIZE`` adjusts automatically the window's size to fit the displayed image (see :ref:`ShowImage` ), and the user can not change the window size manually. - - - * **CV_WINDOW_FREERATIO or CV_WINDOW_KEEPRATIO:** ``CV_WINDOW_FREERATIO`` adjust the image without respect the its ration, whereas ``CV_WINDOW_KEEPRATIO`` keep the image's ratio. - - - * **CV_GUI_NORMAL or CV_GUI_EXPANDED:** ``CV_GUI_NORMAL`` is the old way to draw the window without statusbar and toolbar, whereas ``CV_GUI_EXPANDED`` is the new enhance GUI. - - - - This parameter is optional. The default flags set for a new window are ``CV_WINDOW_AUTOSIZE`` , ``CV_WINDOW_KEEPRATIO`` , and ``CV_GUI_EXPANDED`` . - - However, if you want to modify the flags, you can combine them using OR operator, ie: - - - :: - - - - cvNamedWindow( ``myWindow'', ``CV_WINDOW_NORMAL`` textbar ``CV_GUI_NORMAL`` ); - - - - .. - - - - -.. index:: ResizeWindow - -.. _ResizeWindow: - -ResizeWindow ------------- - - - - - - -.. cfunction:: void cvResizeWindow( const char* name, int width, int height ) - - Sets the window size. - - - - - - - :param name: Name of the window to be resized. - - - :param width: New width - - - :param height: New height - - - -The function -``cvResizeWindow`` -changes the size of the window. - - -.. index:: SetMouseCallback - -.. _SetMouseCallback: - -SetMouseCallback ----------------- - - - - - - -.. cfunction:: void cvSetMouseCallback( const char* windowName, CvMouseCallback onMouse, void* param=NULL ) - - Assigns callback for mouse events. - - - - - - - :param windowName: Name of the window. - - - :param onMouse: Pointer to the function to be called every time a mouse event occurs in the specified window. This function should be prototyped as ``void Foo(int event, int x, int y, int flags, void* param);`` - where ``event`` is one of ``CV_EVENT_*`` , ``x`` and ``y`` are the coordinates of the mouse pointer in image coordinates (not window coordinates), ``flags`` is a combination of ``CV_EVENT_FLAG_*`` , and ``param`` is a user-defined parameter passed to the ``cvSetMouseCallback`` function call. - - - :param param: User-defined parameter to be passed to the callback function. - - - -The function -``cvSetMouseCallback`` -sets the callback function for mouse events occuring within the specified window. - -The -``event`` -parameter is one of: - - - - - * **CV_EVENT_MOUSEMOVE** Mouse movement - - - * **CV_EVENT_LBUTTONDOWN** Left button down - - - * **CV_EVENT_RBUTTONDOWN** Right button down - - - * **CV_EVENT_MBUTTONDOWN** Middle button down - - - * **CV_EVENT_LBUTTONUP** Left button up - - - * **CV_EVENT_RBUTTONUP** Right button up - - - * **CV_EVENT_MBUTTONUP** Middle button up - - - * **CV_EVENT_LBUTTONDBLCLK** Left button double click - - - * **CV_EVENT_RBUTTONDBLCLK** Right button double click - - - * **CV_EVENT_MBUTTONDBLCLK** Middle button double click - - - -The -``flags`` -parameter is a combination of : - - - - - * **CV_EVENT_FLAG_LBUTTON** Left button pressed - - - * **CV_EVENT_FLAG_RBUTTON** Right button pressed - - - * **CV_EVENT_FLAG_MBUTTON** Middle button pressed - - - * **CV_EVENT_FLAG_CTRLKEY** Control key pressed - - - * **CV_EVENT_FLAG_SHIFTKEY** Shift key pressed - - - * **CV_EVENT_FLAG_ALTKEY** Alt key pressed - - - - -.. index:: SetTrackbarPos - -.. _SetTrackbarPos: - -SetTrackbarPos --------------- - - - - - - -.. cfunction:: void cvSetTrackbarPos( const char* trackbarName, const char* windowName, int pos ) - - Sets the trackbar position. - - - - - - - :param trackbarName: Name of the trackbar. - - - :param windowName: Name of the window which is the parent of trackbar. - - - :param pos: New position. - - - -The function -``cvSetTrackbarPos`` -sets the position of the specified trackbar. -\ -\ -**[Qt Backend Only]** -qt-specific details: - - - - * **windowName** Name of the window which is the parent of trackbar. Can be NULL if the trackbar is attached to the control panel. - - - - -.. index:: ShowImage - -.. _ShowImage: - -ShowImage ---------- - - - - - - -.. cfunction:: void cvShowImage( const char* name, const CvArr* image ) - - Displays the image in the specified window - - - - - - - :param name: Name of the window. - - - :param image: Image to be shown. - - - -The function -``cvShowImage`` -displays the image in the specified window. If the window was created with the -``CV_WINDOW_AUTOSIZE`` -flag then the image is shown with its original size, otherwise the image is scaled to fit in the window. The function may scale the image, depending on its depth: - - - - -* - If the image is 8-bit unsigned, it is displayed as is. - - - -* - If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range [0,255*256] is mapped to [0,255]. - - - -* - If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255]. - - - -.. index:: WaitKey - -.. _WaitKey: - -WaitKey -------- - - - - - - -.. cfunction:: int cvWaitKey( int delay=0 ) - - Waits for a pressed key. - - - - - - - :param delay: Delay in milliseconds. - - - -The function -``cvWaitKey`` -waits for key event infinitely ( -:math:`\texttt{delay} <= 0` -) or for -``delay`` -milliseconds. Returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed. - -**Notes:** - -* This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing, unless HighGUI is used within some environment that takes care of event processing. -**[Qt Backend Only]** -qt-specific details: -With this current Qt implementation, this is the only way to process event such as repaint for the windows, and so on -ldots - -* The function only works if there is at least one HighGUI window created and the window is active. If there are several HighGUI windows, any of them can be active. diff --git a/doc/opencv1/c/imgproc.rst b/doc/opencv1/c/imgproc.rst deleted file mode 100644 index 84801cb04e..0000000000 --- a/doc/opencv1/c/imgproc.rst +++ /dev/null @@ -1,18 +0,0 @@ -************************* -imgproc. Image Processing -************************* - - - -.. toctree:: - :maxdepth: 2 - - imgproc_histograms - imgproc_image_filtering - imgproc_geometric_image_transformations - imgproc_miscellaneous_image_transformations - imgproc_structural_analysis_and_shape_descriptors - imgproc_planar_subdivisions - imgproc_motion_analysis_and_object_tracking - imgproc_feature_detection - imgproc_object_detection diff --git a/doc/opencv1/c/imgproc_feature_detection.rst b/doc/opencv1/c/imgproc_feature_detection.rst deleted file mode 100644 index 34fcd6594e..0000000000 --- a/doc/opencv1/c/imgproc_feature_detection.rst +++ /dev/null @@ -1,721 +0,0 @@ -Feature Detection -================= - -.. highlight:: c - - - -.. index:: Canny - -.. _Canny: - -Canny ------ - - - - - - -.. cfunction:: void cvCanny( const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3 ) - - Implements the Canny algorithm for edge detection. - - - - - - - :param image: Single-channel input image - - - :param edges: Single-channel image to store the edges found by the function - - - :param threshold1: The first threshold - - - :param threshold2: The second threshold - - - :param aperture_size: Aperture parameter for the Sobel operator (see :ref:`Sobel` ) - - - -The function finds the edges on the input image -``image`` -and marks them in the output image -``edges`` -using the Canny algorithm. The smallest value between -``threshold1`` -and -``threshold2`` -is used for edge linking, the largest value is used to find the initial segments of strong edges. - - -.. index:: CornerEigenValsAndVecs - -.. _CornerEigenValsAndVecs: - -CornerEigenValsAndVecs ----------------------- - - - - - - -.. cfunction:: void cvCornerEigenValsAndVecs( const CvArr* image, CvArr* eigenvv, int blockSize, int aperture_size=3 ) - - Calculates eigenvalues and eigenvectors of image blocks for corner detection. - - - - - - - :param image: Input image - - - :param eigenvv: Image to store the results. It must be 6 times wider than the input image - - - :param blockSize: Neighborhood size (see discussion) - - - :param aperture_size: Aperture parameter for the Sobel operator (see :ref:`Sobel` ) - - - -For every pixel, the function -``cvCornerEigenValsAndVecs`` -considers a -:math:`\texttt{blockSize} \times \texttt{blockSize}` -neigborhood S(p). It calcualtes the covariation matrix of derivatives over the neigborhood as: - - - -.. math:: - - M = \begin{bmatrix} \sum _{S(p)}(dI/dx)^2 & \sum _{S(p)}(dI/dx \cdot dI/dy)^2 \\ \sum _{S(p)}(dI/dx \cdot dI/dy)^2 & \sum _{S(p)}(dI/dy)^2 \end{bmatrix} - - -After that it finds eigenvectors and eigenvalues of the matrix and stores them into destination image in form -:math:`(\lambda_1, \lambda_2, x_1, y_1, x_2, y_2)` -where - - - - -* :math:`\lambda_1, \lambda_2` - are the eigenvalues of - :math:`M` - ; not sorted - - -* :math:`x_1, y_1` - are the eigenvectors corresponding to - :math:`\lambda_1` - - -* :math:`x_2, y_2` - are the eigenvectors corresponding to - :math:`\lambda_2` - - - -.. index:: CornerHarris - -.. _CornerHarris: - -CornerHarris ------------- - - - - - - -.. cfunction:: void cvCornerHarris( const CvArr* image, CvArr* harris_dst, int blockSize, int aperture_size=3, double k=0.04 ) - - Harris edge detector. - - - - - - - :param image: Input image - - - :param harris_dst: Image to store the Harris detector responses. Should have the same size as ``image`` - - - :param blockSize: Neighborhood size (see the discussion of :ref:`CornerEigenValsAndVecs` ) - - - :param aperture_size: Aperture parameter for the Sobel operator (see :ref:`Sobel` ). - - - :param k: Harris detector free parameter. See the formula below - - - -The function runs the Harris edge detector on the image. Similarly to -:ref:`CornerMinEigenVal` -and -:ref:`CornerEigenValsAndVecs` -, for each pixel it calculates a -:math:`2\times2` -gradient covariation matrix -:math:`M` -over a -:math:`\texttt{blockSize} \times \texttt{blockSize}` -neighborhood. Then, it stores - - - -.. math:: - - det(M) - k \, trace(M)^2 - - -to the destination image. Corners in the image can be found as the local maxima of the destination image. - - -.. index:: CornerMinEigenVal - -.. _CornerMinEigenVal: - -CornerMinEigenVal ------------------ - - - - - - -.. cfunction:: void cvCornerMinEigenVal( const CvArr* image, CvArr* eigenval, int blockSize, int aperture_size=3 ) - - Calculates the minimal eigenvalue of gradient matrices for corner detection. - - - - - - - :param image: Input image - - - :param eigenval: Image to store the minimal eigenvalues. Should have the same size as ``image`` - - - :param blockSize: Neighborhood size (see the discussion of :ref:`CornerEigenValsAndVecs` ) - - - :param aperture_size: Aperture parameter for the Sobel operator (see :ref:`Sobel` ). - - - -The function is similar to -:ref:`CornerEigenValsAndVecs` -but it calculates and stores only the minimal eigen value of derivative covariation matrix for every pixel, i.e. -:math:`min(\lambda_1, \lambda_2)` -in terms of the previous function. - - -.. index:: FindCornerSubPix - -.. _FindCornerSubPix: - -FindCornerSubPix ----------------- - - - - - - -.. cfunction:: void cvFindCornerSubPix( const CvArr* image, CvPoint2D32f* corners, int count, CvSize win, CvSize zero_zone, CvTermCriteria criteria ) - - Refines the corner locations. - - - - - - - :param image: Input image - - - :param corners: Initial coordinates of the input corners; refined coordinates on output - - - :param count: Number of corners - - - :param win: Half of the side length of the search window. For example, if ``win`` =(5,5), then a :math:`5*2+1 \times 5*2+1 = 11 \times 11` search window would be used - - - :param zero_zone: Half of the size of the dead region in the middle of the search zone over which the summation in the formula below is not done. It is used sometimes to avoid possible singularities of the autocorrelation matrix. The value of (-1,-1) indicates that there is no such size - - - :param criteria: Criteria for termination of the iterative process of corner refinement. That is, the process of corner position refinement stops either after a certain number of iterations or when a required accuracy is achieved. The ``criteria`` may specify either of or both the maximum number of iteration and the required accuracy - - - -The function iterates to find the sub-pixel accurate location of corners, or radial saddle points, as shown in on the picture below. - - -.. image:: ../pics/cornersubpix.png - - - -Sub-pixel accurate corner locator is based on the observation that every vector from the center -:math:`q` -to a point -:math:`p` -located within a neighborhood of -:math:`q` -is orthogonal to the image gradient at -:math:`p` -subject to image and measurement noise. Consider the expression: - - - -.. math:: - - \epsilon _i = {DI_{p_i}}^T \cdot (q - p_i) - - -where -:math:`{DI_{p_i}}` -is the image gradient at the one of the points -:math:`p_i` -in a neighborhood of -:math:`q` -. The value of -:math:`q` -is to be found such that -:math:`\epsilon_i` -is minimized. A system of equations may be set up with -:math:`\epsilon_i` -set to zero: - - - -.. math:: - - \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T) q = \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T \cdot p_i) - - -where the gradients are summed within a neighborhood ("search window") of -:math:`q` -. Calling the first gradient term -:math:`G` -and the second gradient term -:math:`b` -gives: - - - -.. math:: - - q = G^{-1} \cdot b - - -The algorithm sets the center of the neighborhood window at this new center -:math:`q` -and then iterates until the center keeps within a set threshold. - - -.. index:: GoodFeaturesToTrack - -.. _GoodFeaturesToTrack: - -GoodFeaturesToTrack -------------------- - - - - - - -.. cfunction:: void cvGoodFeaturesToTrack( const CvArr* image CvArr* eigImage, CvArr* tempImage CvPoint2D32f* corners int* cornerCount double qualityLevel double minDistance const CvArr* mask=NULL int blockSize=3 int useHarris=0 double k=0.04 ) - - Determines strong corners on an image. - - - - - - - :param image: The source 8-bit or floating-point 32-bit, single-channel image - - - :param eigImage: Temporary floating-point 32-bit image, the same size as ``image`` - - - :param tempImage: Another temporary image, the same size and format as ``eigImage`` - - - :param corners: Output parameter; detected corners - - - :param cornerCount: Output parameter; number of detected corners - - - :param qualityLevel: Multiplier for the max/min eigenvalue; specifies the minimal accepted quality of image corners - - - :param minDistance: Limit, specifying the minimum possible distance between the returned corners; Euclidian distance is used - - - :param mask: Region of interest. The function selects points either in the specified region or in the whole image if the mask is NULL - - - :param blockSize: Size of the averaging block, passed to the underlying :ref:`CornerMinEigenVal` or :ref:`CornerHarris` used by the function - - - :param useHarris: If nonzero, Harris operator ( :ref:`CornerHarris` ) is used instead of default :ref:`CornerMinEigenVal` - - - :param k: Free parameter of Harris detector; used only if ( :math:`\texttt{useHarris} != 0` ) - - - -The function finds the corners with big eigenvalues in the image. The function first calculates the minimal -eigenvalue for every source image pixel using the -:ref:`CornerMinEigenVal` -function and stores them in -``eigImage`` -. Then it performs -non-maxima suppression (only the local maxima in -:math:`3\times 3` -neighborhood -are retained). The next step rejects the corners with the minimal -eigenvalue less than -:math:`\texttt{qualityLevel} \cdot max(\texttt{eigImage}(x,y))` -. -Finally, the function ensures that the distance between any two corners is not smaller than -``minDistance`` -. The weaker corners (with a smaller min eigenvalue) that are too close to the stronger corners are rejected. - -Note that the if the function is called with different values -``A`` -and -``B`` -of the parameter -``qualityLevel`` -, and -``A`` -> {B}, the array of returned corners with -``qualityLevel=A`` -will be the prefix of the output corners array with -``qualityLevel=B`` -. - - -.. index:: HoughLines2 - -.. _HoughLines2: - -HoughLines2 ------------ - - - - - - -.. cfunction:: CvSeq* cvHoughLines2( CvArr* image, void* storage, int method, double rho, double theta, int threshold, double param1=0, double param2=0 ) - - Finds lines in a binary image using a Hough transform. - - - - - - - :param image: The 8-bit, single-channel, binary source image. In the case of a probabilistic method, the image is modified by the function - - - :param storage: The storage for the lines that are detected. It can - be a memory storage (in this case a sequence of lines is created in - the storage and returned by the function) or single row/single column - matrix (CvMat*) of a particular type (see below) to which the lines' - parameters are written. The matrix header is modified by the function - so its ``cols`` or ``rows`` will contain the number of lines - detected. If ``storage`` is a matrix and the actual number - of lines exceeds the matrix size, the maximum possible number of lines - is returned (in the case of standard hough transform the lines are sorted - by the accumulator value) - - - :param method: The Hough transform variant, one of the following: - - - * **CV_HOUGH_STANDARD** classical or standard Hough transform. Every line is represented by two floating-point numbers :math:`(\rho, \theta)` , where :math:`\rho` is a distance between (0,0) point and the line, and :math:`\theta` is the angle between x-axis and the normal to the line. Thus, the matrix must be (the created sequence will be) of ``CV_32FC2`` type - - - * **CV_HOUGH_PROBABILISTIC** probabilistic Hough transform (more efficient in case if picture contains a few long linear segments). It returns line segments rather than the whole line. Each segment is represented by starting and ending points, and the matrix must be (the created sequence will be) of ``CV_32SC4`` type - - - * **CV_HOUGH_MULTI_SCALE** multi-scale variant of the classical Hough transform. The lines are encoded the same way as ``CV_HOUGH_STANDARD`` - - - - - :param rho: Distance resolution in pixel-related units - - - :param theta: Angle resolution measured in radians - - - :param threshold: Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than ``threshold`` - - - :param param1: The first method-dependent parameter: - - - - * For the classical Hough transform it is not used (0). - - - * For the probabilistic Hough transform it is the minimum line length. - - - * For the multi-scale Hough transform it is the divisor for the distance resolution :math:`\rho` . (The coarse distance resolution will be :math:`\rho` and the accurate resolution will be :math:`(\rho / \texttt{param1})` ). - - - - :param param2: The second method-dependent parameter: - - - - * For the classical Hough transform it is not used (0). - - - * For the probabilistic Hough transform it is the maximum gap between line segments lying on the same line to treat them as a single line segment (i.e. to join them). - - - * For the multi-scale Hough transform it is the divisor for the angle resolution :math:`\theta` . (The coarse angle resolution will be :math:`\theta` and the accurate resolution will be :math:`(\theta / \texttt{param2})` ). - - - - -The function implements a few variants of the Hough transform for line detection. - -**Example. Detecting lines with Hough transform.** - - - -:: - - - - /* This is a standalone program. Pass an image name as a first parameter - of the program. Switch between standard and probabilistic Hough transform - by changing "#if 1" to "#if 0" and back */ - #include - #include - #include - - int main(int argc, char** argv) - { - IplImage* src; - if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0) - { - IplImage* dst = cvCreateImage( cvGetSize(src), 8, 1 ); - IplImage* color_dst = cvCreateImage( cvGetSize(src), 8, 3 ); - CvMemStorage* storage = cvCreateMemStorage(0); - CvSeq* lines = 0; - int i; - cvCanny( src, dst, 50, 200, 3 ); - cvCvtColor( dst, color_dst, CV_GRAY2BGR ); - #if 1 - lines = cvHoughLines2( dst, - storage, - CV_HOUGH_STANDARD, - 1, - CV_PI/180, - 100, - 0, - 0 ); - - for( i = 0; i < MIN(lines->total,100); i++ ) - { - float* line = (float*)cvGetSeqElem(lines,i); - float rho = line[0]; - float theta = line[1]; - CvPoint pt1, pt2; - double a = cos(theta), b = sin(theta); - double x0 = a*rho, y0 = b*rho; - pt1.x = cvRound(x0 + 1000*(-b)); - pt1.y = cvRound(y0 + 1000*(a)); - pt2.x = cvRound(x0 - 1000*(-b)); - pt2.y = cvRound(y0 - 1000*(a)); - cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, 8 ); - } - #else - lines = cvHoughLines2( dst, - storage, - CV_HOUGH_PROBABILISTIC, - 1, - CV_PI/180, - 80, - 30, - 10 ); - for( i = 0; i < lines->total; i++ ) - { - CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i); - cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, 8 ); - } - #endif - cvNamedWindow( "Source", 1 ); - cvShowImage( "Source", src ); - - cvNamedWindow( "Hough", 1 ); - cvShowImage( "Hough", color_dst ); - - cvWaitKey(0); - } - } - - -.. - -This is the sample picture the function parameters have been tuned for: - - - -.. image:: ../pics/building.jpg - - - -And this is the output of the above program in the case of probabilistic Hough transform ( -``#if 0`` -case): - - - -.. image:: ../pics/houghp.png - - - - -.. index:: PreCornerDetect - -.. _PreCornerDetect: - -PreCornerDetect ---------------- - - - - - - -.. cfunction:: void cvPreCornerDetect( const CvArr* image, CvArr* corners, int apertureSize=3 ) - - Calculates the feature map for corner detection. - - - - - - - :param image: Input image - - - :param corners: Image to store the corner candidates - - - :param apertureSize: Aperture parameter for the Sobel operator (see :ref:`Sobel` ) - - - -The function calculates the function - - - -.. math:: - - D_x^2 D_{yy} + D_y^2 D_{xx} - 2 D_x D_y D_{xy} - - -where -:math:`D_?` -denotes one of the first image derivatives and -:math:`D_{??}` -denotes a second image derivative. - -The corners can be found as local maximums of the function below: - - - - -:: - - - - // assume that the image is floating-point - IplImage* corners = cvCloneImage(image); - IplImage* dilated_corners = cvCloneImage(image); - IplImage* corner_mask = cvCreateImage( cvGetSize(image), 8, 1 ); - cvPreCornerDetect( image, corners, 3 ); - cvDilate( corners, dilated_corners, 0, 1 ); - cvSubS( corners, dilated_corners, corners ); - cvCmpS( corners, 0, corner_mask, CV_CMP_GE ); - cvReleaseImage( &corners ); - cvReleaseImage( &dilated_corners ); - - -.. - - -.. index:: SampleLine - -.. _SampleLine: - -SampleLine ----------- - - - - - - -.. cfunction:: int cvSampleLine( const CvArr* image CvPoint pt1 CvPoint pt2 void* buffer int connectivity=8 ) - - Reads the raster line to the buffer. - - - - - - - :param image: Image to sample the line from - - - :param pt1: Starting line point - - - :param pt2: Ending line point - - - :param buffer: Buffer to store the line points; must have enough size to store :math:`max( |\texttt{pt2.x} - \texttt{pt1.x}|+1, |\texttt{pt2.y} - \texttt{pt1.y}|+1 )` - points in the case of an 8-connected line and :math:`(|\texttt{pt2.x}-\texttt{pt1.x}|+|\texttt{pt2.y}-\texttt{pt1.y}|+1)` - in the case of a 4-connected line - - - :param connectivity: The line connectivity, 4 or 8 - - - -The function implements a particular application of line iterators. The function reads all of the image points lying on the line between -``pt1`` -and -``pt2`` -, including the end points, and stores them into the buffer. - diff --git a/doc/opencv1/c/imgproc_geometric_image_transformations.rst b/doc/opencv1/c/imgproc_geometric_image_transformations.rst deleted file mode 100644 index fb4553bea6..0000000000 --- a/doc/opencv1/c/imgproc_geometric_image_transformations.rst +++ /dev/null @@ -1,737 +0,0 @@ -Geometric Image Transformations -=============================== - -.. highlight:: c - - -The functions in this section perform various geometrical transformations of 2D images. That is, they do not change the image content, but deform the pixel grid, and map this deformed grid to the destination image. In fact, to avoid sampling artifacts, the mapping is done in the reverse order, from destination to the source. That is, for each pixel -:math:`(x, y)` -of the destination image, the functions compute coordinates of the corresponding "donor" pixel in the source image and copy the pixel value, that is: - - - -.. math:: - - \texttt{dst} (x,y)= \texttt{src} (f_x(x,y), f_y(x,y)) - - -In the case when the user specifies the forward mapping: -:math:`\left: \texttt{src} \rightarrow \texttt{dst}` -, the OpenCV functions first compute the corresponding inverse mapping: -:math:`\left: \texttt{dst} \rightarrow \texttt{src}` -and then use the above formula. - -The actual implementations of the geometrical transformations, from the most generic -:ref:`Remap` -and to the simplest and the fastest -:ref:`Resize` -, need to solve the 2 main problems with the above formula: - - - - -#. - extrapolation of non-existing pixels. Similarly to the filtering functions, described in the previous section, for some - :math:`(x,y)` - one of - :math:`f_x(x,y)` - or - :math:`f_y(x,y)` - , or they both, may fall outside of the image, in which case some extrapolation method needs to be used. OpenCV provides the same selection of the extrapolation methods as in the filtering functions, but also an additional method - ``BORDER_TRANSPARENT`` - , which means that the corresponding pixels in the destination image will not be modified at all. - - - -#. - interpolation of pixel values. Usually - :math:`f_x(x,y)` - and - :math:`f_y(x,y)` - are floating-point numbers (i.e. - :math:`\left` - can be an affine or perspective transformation, or radial lens distortion correction etc.), so a pixel values at fractional coordinates needs to be retrieved. In the simplest case the coordinates can be just rounded to the nearest integer coordinates and the corresponding pixel used, which is called nearest-neighbor interpolation. However, a better result can be achieved by using more sophisticated - `interpolation methods `_ - , where a polynomial function is fit into some neighborhood of the computed pixel - :math:`(f_x(x,y), f_y(x,y))` - and then the value of the polynomial at - :math:`(f_x(x,y), f_y(x,y))` - is taken as the interpolated pixel value. In OpenCV you can choose between several interpolation methods, see - :ref:`Resize` - . - - - -.. index:: GetRotationMatrix2D - -.. _GetRotationMatrix2D: - -GetRotationMatrix2D -------------------- - - - - - - -.. cfunction:: CvMat* cv2DRotationMatrix( CvPoint2D32f center, double angle, double scale, CvMat* mapMatrix ) - - Calculates the affine matrix of 2d rotation. - - - - - - - :param center: Center of the rotation in the source image - - - :param angle: The rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner) - - - :param scale: Isotropic scale factor - - - :param mapMatrix: Pointer to the destination :math:`2\times 3` matrix - - - -The function -``cv2DRotationMatrix`` -calculates the following matrix: - - - -.. math:: - - \begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\ - \beta & \alpha & \beta \cdot \texttt{center.x} - (1- \alpha ) \cdot \texttt{center.y} \end{bmatrix} - - -where - - - -.. math:: - - \alpha = \texttt{scale} \cdot cos( \texttt{angle} ), \beta = \texttt{scale} \cdot sin( \texttt{angle} ) - - -The transformation maps the rotation center to itself. If this is not the purpose, the shift should be adjusted. - - -.. index:: GetAffineTransform - -.. _GetAffineTransform: - -GetAffineTransform ------------------- - - - - - - -.. cfunction:: CvMat* cvGetAffineTransform( const CvPoint2D32f* src, const CvPoint2D32f* dst, CvMat* mapMatrix ) - - Calculates the affine transform from 3 corresponding points. - - - - - - - :param src: Coordinates of 3 triangle vertices in the source image - - - :param dst: Coordinates of the 3 corresponding triangle vertices in the destination image - - - :param mapMatrix: Pointer to the destination :math:`2 \times 3` matrix - - - -The function cvGetAffineTransform calculates the matrix of an affine transform such that: - - - -.. math:: - - \begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} - - -where - - - -.. math:: - - dst(i)=(x'_i,y'_i), - src(i)=(x_i, y_i), - i=0,1,2 - - - -.. index:: GetPerspectiveTransform - -.. _GetPerspectiveTransform: - -GetPerspectiveTransform ------------------------ - - - - - - -.. cfunction:: CvMat* cvGetPerspectiveTransform( const CvPoint2D32f* src, const CvPoint2D32f* dst, CvMat* mapMatrix ) - - Calculates the perspective transform from 4 corresponding points. - - - - - - - :param src: Coordinates of 4 quadrangle vertices in the source image - - - :param dst: Coordinates of the 4 corresponding quadrangle vertices in the destination image - - - :param mapMatrix: Pointer to the destination :math:`3\times 3` matrix - - - -The function -``cvGetPerspectiveTransform`` -calculates a matrix of perspective transforms such that: - - - -.. math:: - - \begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} - - -where - - - -.. math:: - - dst(i)=(x'_i,y'_i), - src(i)=(x_i, y_i), - i=0,1,2,3 - - - -.. index:: GetQuadrangleSubPix - -.. _GetQuadrangleSubPix: - -GetQuadrangleSubPix -------------------- - - - - - - -.. cfunction:: void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* mapMatrix ) - - Retrieves the pixel quadrangle from an image with sub-pixel accuracy. - - - - - - - :param src: Source image - - - :param dst: Extracted quadrangle - - - :param mapMatrix: The transformation :math:`2 \times 3` matrix :math:`[A|b]` (see the discussion) - - - -The function -``cvGetQuadrangleSubPix`` -extracts pixels from -``src`` -at sub-pixel accuracy and stores them to -``dst`` -as follows: - - - -.. math:: - - dst(x, y)= src( A_{11} x' + A_{12} y' + b_1, A_{21} x' + A_{22} y' + b_2) - - -where - - - -.. math:: - - x'=x- \frac{(width(dst)-1)}{2} , - y'=y- \frac{(height(dst)-1)}{2} - - -and - - - -.. math:: - - \texttt{mapMatrix} = \begin{bmatrix} A_{11} & A_{12} & b_1 \\ A_{21} & A_{22} & b_2 \end{bmatrix} - - -The values of pixels at non-integer coordinates are retrieved using bilinear interpolation. When the function needs pixels outside of the image, it uses replication border mode to reconstruct the values. Every channel of multiple-channel images is processed independently. - - - -.. index:: GetRectSubPix - -.. _GetRectSubPix: - -GetRectSubPix -------------- - - - - - - -.. cfunction:: void cvGetRectSubPix( const CvArr* src, CvArr* dst, CvPoint2D32f center ) - - Retrieves the pixel rectangle from an image with sub-pixel accuracy. - - - - - - - :param src: Source image - - - :param dst: Extracted rectangle - - - :param center: Floating point coordinates of the extracted rectangle center within the source image. The center must be inside the image - - - -The function -``cvGetRectSubPix`` -extracts pixels from -``src`` -: - - - -.. math:: - - dst(x, y) = src(x + \texttt{center.x} - (width( \texttt{dst} )-1)*0.5, y + \texttt{center.y} - (height( \texttt{dst} )-1)*0.5) - - -where the values of the pixels at non-integer coordinates are retrieved -using bilinear interpolation. Every channel of multiple-channel -images is processed independently. While the rectangle center -must be inside the image, parts of the rectangle may be -outside. In this case, the replication border mode is used to get -pixel values beyond the image boundaries. - - - -.. index:: LogPolar - -.. _LogPolar: - -LogPolar --------- - - - - - - -.. cfunction:: void cvLogPolar( const CvArr* src, CvArr* dst, CvPoint2D32f center, double M, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ) - - Remaps an image to log-polar space. - - - - - - - :param src: Source image - - - :param dst: Destination image - - - :param center: The transformation center; where the output precision is maximal - - - :param M: Magnitude scale parameter. See below - - - :param flags: A combination of interpolation methods and the following optional flags: - - - * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero - - - * **CV_WARP_INVERSE_MAP** See below - - - - - -The function -``cvLogPolar`` -transforms the source image using the following transformation: - -Forward transformation ( -``CV_WARP_INVERSE_MAP`` -is not set): - - - -.. math:: - - dst( \phi , \rho ) = src(x,y) - - -Inverse transformation ( -``CV_WARP_INVERSE_MAP`` -is set): - - - -.. math:: - - dst(x,y) = src( \phi , \rho ) - - -where - - - -.. math:: - - \rho = M \cdot \log{\sqrt{x^2 + y^2}} , \phi =atan(y/x) - - -The function emulates the human "foveal" vision and can be used for fast scale and rotation-invariant template matching, for object tracking and so forth. -The function can not operate in-place. - - - - -:: - - - - #include - #include - - int main(int argc, char** argv) - { - IplImage* src; - - if( argc == 2 && (src=cvLoadImage(argv[1],1) != 0 ) - { - IplImage* dst = cvCreateImage( cvSize(256,256), 8, 3 ); - IplImage* src2 = cvCreateImage( cvGetSize(src), 8, 3 ); - cvLogPolar( src, dst, cvPoint2D32f(src->width/2,src->height/2), 40, - CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ); - cvLogPolar( dst, src2, cvPoint2D32f(src->width/2,src->height/2), 40, - CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+CV_WARP_INVERSE_MAP ); - cvNamedWindow( "log-polar", 1 ); - cvShowImage( "log-polar", dst ); - cvNamedWindow( "inverse log-polar", 1 ); - cvShowImage( "inverse log-polar", src2 ); - cvWaitKey(); - } - return 0; - } - - -.. - -And this is what the program displays when -``opencv/samples/c/fruits.jpg`` -is passed to it - - -.. image:: ../pics/logpolar.jpg - - - - - -.. image:: ../pics/inv_logpolar.jpg - - - - -.. index:: Remap - -.. _Remap: - -Remap ------ - - - - - - -.. cfunction:: void cvRemap( const CvArr* src, CvArr* dst, const CvArr* mapx, const CvArr* mapy, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ) - - Applies a generic geometrical transformation to the image. - - - - - - - :param src: Source image - - - :param dst: Destination image - - - :param mapx: The map of x-coordinates (CV _ 32FC1 image) - - - :param mapy: The map of y-coordinates (CV _ 32FC1 image) - - - :param flags: A combination of interpolation method and the following optional flag(s): - - - * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to ``fillval`` - - - - - :param fillval: A value used to fill outliers - - - -The function -``cvRemap`` -transforms the source image using the specified map: - - - -.. math:: - - \texttt{dst} (x,y) = \texttt{src} ( \texttt{mapx} (x,y), \texttt{mapy} (x,y)) - - -Similar to other geometrical transformations, some interpolation method (specified by user) is used to extract pixels with non-integer coordinates. -Note that the function can not operate in-place. - - -.. index:: Resize - -.. _Resize: - -Resize ------- - - - - - - -.. cfunction:: void cvResize( const CvArr* src, CvArr* dst, int interpolation=CV_INTER_LINEAR ) - - Resizes an image. - - - - - - - :param src: Source image - - - :param dst: Destination image - - - :param interpolation: Interpolation method: - - * **CV_INTER_NN** nearest-neigbor interpolation - - * **CV_INTER_LINEAR** bilinear interpolation (used by default) - - * **CV_INTER_AREA** resampling using pixel area relation. It is the preferred method for image decimation that gives moire-free results. In terms of zooming it is similar to the ``CV_INTER_NN`` method - - * **CV_INTER_CUBIC** bicubic interpolation - - - - - -The function -``cvResize`` -resizes an image -``src`` -so that it fits exactly into -``dst`` -. If ROI is set, the function considers the ROI as supported. - - - -.. index:: WarpAffine - -.. _WarpAffine: - -WarpAffine ----------- - - - - - - -.. cfunction:: void cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* mapMatrix, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ) - - Applies an affine transformation to an image. - - - - - - - :param src: Source image - - - :param dst: Destination image - - - :param mapMatrix: :math:`2\times 3` transformation matrix - - - :param flags: A combination of interpolation methods and the following optional flags: - - - * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels; if some of them correspond to outliers in the source image, they are set to ``fillval`` - - - * **CV_WARP_INVERSE_MAP** indicates that ``matrix`` is inversely - transformed from the destination image to the source and, thus, can be used - directly for pixel interpolation. Otherwise, the function finds - the inverse transform from ``mapMatrix`` - - - - - - :param fillval: A value used to fill outliers - - - -The function -``cvWarpAffine`` -transforms the source image using the specified matrix: - - - -.. math:: - - dst(x',y') = src(x,y) - - -where - - - -.. math:: - - \begin{matrix} \begin{bmatrix} x' \\ y' \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} & \mbox{if CV\_WARP\_INVERSE\_MAP is not set} \\ \begin{bmatrix} x \\ y \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} & \mbox{otherwise} \end{matrix} - - -The function is similar to -:ref:`GetQuadrangleSubPix` -but they are not exactly the same. -:ref:`WarpAffine` -requires input and output image have the same data type, has larger overhead (so it is not quite suitable for small images) and can leave part of destination image unchanged. While -:ref:`GetQuadrangleSubPix` -may extract quadrangles from 8-bit images into floating-point buffer, has smaller overhead and always changes the whole destination image content. -Note that the function can not operate in-place. - -To transform a sparse set of points, use the -:ref:`Transform` -function from cxcore. - - -.. index:: WarpPerspective - -.. _WarpPerspective: - -WarpPerspective ---------------- - - - - - - -.. cfunction:: void cvWarpPerspective( const CvArr* src, CvArr* dst, const CvMat* mapMatrix, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ) - - Applies a perspective transformation to an image. - - - - - - - :param src: Source image - - - :param dst: Destination image - - - :param mapMatrix: :math:`3\times 3` transformation matrix - - - :param flags: A combination of interpolation methods and the following optional flags: - - - * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels; if some of them correspond to outliers in the source image, they are set to ``fillval`` - - - * **CV_WARP_INVERSE_MAP** indicates that ``matrix`` is inversely transformed from the destination image to the source and, thus, can be used directly for pixel interpolation. Otherwise, the function finds the inverse transform from ``mapMatrix`` - - - - - :param fillval: A value used to fill outliers - - - -The function -``cvWarpPerspective`` -transforms the source image using the specified matrix: - - - -.. math:: - - \begin{matrix} \begin{bmatrix} x' \\ y' \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} & \mbox{if CV\_WARP\_INVERSE\_MAP is not set} \\ \begin{bmatrix} x \\ y \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} & \mbox{otherwise} \end{matrix} - - -Note that the function can not operate in-place. -For a sparse set of points use the -:ref:`PerspectiveTransform` -function from CxCore. - diff --git a/doc/opencv1/c/imgproc_histograms.rst b/doc/opencv1/c/imgproc_histograms.rst deleted file mode 100644 index 623ff9e8d2..0000000000 --- a/doc/opencv1/c/imgproc_histograms.rst +++ /dev/null @@ -1,941 +0,0 @@ -Histograms -========== - -.. highlight:: c - - - -.. index:: CvHistogram - -.. _CvHistogram: - -CvHistogram ------------ - - - -.. ctype:: CvHistogram - - - -Multi-dimensional histogram. - - - - -:: - - - - 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 */ - } - CvHistogram; - - -.. - - -.. index:: CalcBackProject - -.. _CalcBackProject: - -CalcBackProject ---------------- - - - - - - -.. cfunction:: void cvCalcBackProject( IplImage** image, CvArr* back_project, const CvHistogram* hist ) - - Calculates the back projection. - - - - - - - :param image: Source images (though you may pass CvMat** as well) - - - :param back_project: Destination back projection image of the same type as the source images - - - :param hist: Histogram - - - -The function calculates the back project of the histogram. For each -tuple of pixels at the same position of all input single-channel images -the function puts the value of the histogram bin, corresponding to the -tuple in the destination image. In terms of statistics, the value of -each output image pixel is the probability of the observed tuple given -the distribution (histogram). For example, to find a red object in the -picture, one may do the following: - - - - - -#. - Calculate a hue histogram for the red object assuming the image contains only this object. The histogram is likely to have a strong maximum, corresponding to red color. - - - -#. - Calculate back projection of a hue plane of input image where the object is searched, using the histogram. Threshold the image. - - - -#. - Find connected components in the resulting picture and choose the right component using some additional criteria, for example, the largest connected component. - - -That is the approximate algorithm of Camshift color object tracker, except for the 3rd step, instead of which CAMSHIFT algorithm is used to locate the object on the back projection given the previous object position. - - -.. index:: CalcBackProjectPatch - -.. _CalcBackProjectPatch: - -CalcBackProjectPatch --------------------- - - - - - - -.. cfunction:: void cvCalcBackProjectPatch( IplImage** images, CvArr* dst, CvSize patch_size, CvHistogram* hist, int method, double factor ) - - Locates a template within an image by using a histogram comparison. - - - - - - - :param images: Source images (though, you may pass CvMat** as well) - - - :param dst: Destination image - - - :param patch_size: Size of the patch slid though the source image - - - :param hist: Histogram - - - :param method: Comparison method, passed to :ref:`CompareHist` (see description of that function) - - - :param factor: Normalization factor for histograms, will affect the normalization scale of the destination image, pass 1 if unsure - - - -The function calculates the back projection by comparing histograms of the source image patches with the given histogram. Taking measurement results from some image at each location over ROI creates an array -``image`` -. These results might be one or more of hue, -``x`` -derivative, -``y`` -derivative, Laplacian filter, oriented Gabor filter, etc. Each measurement output is collected into its own separate image. The -``image`` -image array is a collection of these measurement images. A multi-dimensional histogram -``hist`` -is constructed by sampling from the -``image`` -image array. The final histogram is normalized. The -``hist`` -histogram has as many dimensions as the number of elements in -``image`` -array. - -Each new image is measured and then converted into an -``image`` -image array over a chosen ROI. Histograms are taken from this -``image`` -image in an area covered by a "patch" with an anchor at center as shown in the picture below. The histogram is normalized using the parameter -``norm_factor`` -so that it may be compared with -``hist`` -. The calculated histogram is compared to the model histogram; -``hist`` -uses The function -``cvCompareHist`` -with the comparison method= -``method`` -). The resulting output is placed at the location corresponding to the patch anchor in the probability image -``dst`` -. This process is repeated as the patch is slid over the ROI. Iterative histogram update by subtracting trailing pixels covered by the patch and adding newly covered pixels to the histogram can save a lot of operations, though it is not implemented yet. - -Back Project Calculation by Patches - - - -.. image:: ../pics/backprojectpatch.png - - - - -.. index:: CalcHist - -.. _CalcHist: - -CalcHist --------- - - - - - - -.. cfunction:: void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL ) - - Calculates the histogram of image(s). - - - - - - - :param image: Source images (though you may pass CvMat** as well) - - - :param hist: Pointer to the histogram - - - :param accumulate: Accumulation flag. If it is set, the histogram is not cleared in the beginning. This feature allows user to compute a single histogram from several images, or to update the histogram online - - - :param mask: The operation mask, determines what pixels of the source images are counted - - - -The function calculates the histogram of one or more -single-channel images. The elements of a tuple that is used to increment -a histogram bin are taken at the same location from the corresponding -input images. - - - - -:: - - - - #include - #include - - int main( int argc, char** argv ) - { - IplImage* src; - if( argc == 2 && (src=cvLoadImage(argv[1], 1))!= 0) - { - IplImage* h_plane = cvCreateImage( cvGetSize(src), 8, 1 ); - IplImage* s_plane = cvCreateImage( cvGetSize(src), 8, 1 ); - IplImage* v_plane = cvCreateImage( cvGetSize(src), 8, 1 ); - IplImage* planes[] = { h_plane, s_plane }; - IplImage* hsv = cvCreateImage( cvGetSize(src), 8, 3 ); - int h_bins = 30, s_bins = 32; - int hist_size[] = {h_bins, s_bins}; - /* hue varies from 0 (~0 deg red) to 180 (~360 deg red again) */ - float h_ranges[] = { 0, 180 }; - /* saturation varies from 0 (black-gray-white) to - 255 (pure spectrum color) */ - float s_ranges[] = { 0, 255 }; - float* ranges[] = { h_ranges, s_ranges }; - int scale = 10; - IplImage* hist_img = - cvCreateImage( cvSize(h_bins*scale,s_bins*scale), 8, 3 ); - CvHistogram* hist; - float max_value = 0; - int h, s; - - cvCvtColor( src, hsv, CV_BGR2HSV ); - cvCvtPixToPlane( hsv, h_plane, s_plane, v_plane, 0 ); - hist = cvCreateHist( 2, hist_size, CV_HIST_ARRAY, ranges, 1 ); - cvCalcHist( planes, hist, 0, 0 ); - cvGetMinMaxHistValue( hist, 0, &max_value, 0, 0 ); - cvZero( hist_img ); - - for( h = 0; h < h_bins; h++ ) - { - for( s = 0; s < s_bins; s++ ) - { - float bin_val = cvQueryHistValue_2D( hist, h, s ); - int intensity = cvRound(bin_val*255/max_value); - cvRectangle( hist_img, cvPoint( h*scale, s*scale ), - cvPoint( (h+1)*scale - 1, (s+1)*scale - 1), - CV_RGB(intensity,intensity,intensity), - CV_FILLED ); - } - } - - cvNamedWindow( "Source", 1 ); - cvShowImage( "Source", src ); - - cvNamedWindow( "H-S Histogram", 1 ); - cvShowImage( "H-S Histogram", hist_img ); - - cvWaitKey(0); - } - } - - -.. - - -.. index:: CalcProbDensity - -.. _CalcProbDensity: - -CalcProbDensity ---------------- - - - - - - -.. cfunction:: void cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2, CvHistogram* dst_hist, double scale=255 ) - - Divides one histogram by another. - - - - - - - :param hist1: first histogram (the divisor) - - - :param hist2: second histogram - - - :param dst_hist: destination histogram - - - :param scale: scale factor for the destination histogram - - - -The function calculates the object probability density from the two histograms as: - - - -.. math:: - - \texttt{dist\_hist} (I)= \forkthree{0}{if $\texttt{hist1}(I)=0$}{\texttt{scale}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) > \texttt{hist1}(I)$}{\frac{\texttt{hist2}(I) \cdot \texttt{scale}}{\texttt{hist1}(I)}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) \le \texttt{hist1}(I)$} - - -So the destination histogram bins are within less than -``scale`` -. - - -.. index:: ClearHist - -.. _ClearHist: - -ClearHist ---------- - - - - - - -.. cfunction:: void cvClearHist( CvHistogram* hist ) - - Clears the histogram. - - - - - - - :param hist: Histogram - - - -The function sets all of the histogram bins to 0 in the case of a dense histogram and removes all histogram bins in the case of a sparse array. - - -.. index:: CompareHist - -.. _CompareHist: - -CompareHist ------------ - - - - - - -.. cfunction:: double cvCompareHist( const CvHistogram* hist1, const CvHistogram* hist2, int method ) - - Compares two dense histograms. - - - - - - - :param hist1: The first dense histogram - - - :param hist2: The second dense histogram - - - :param method: Comparison method, one of the following: - - - * **CV_COMP_CORREL** Correlation - - - * **CV_COMP_CHISQR** Chi-Square - - - * **CV_COMP_INTERSECT** Intersection - - - * **CV_COMP_BHATTACHARYYA** Bhattacharyya distance - - - - - -The function compares two dense histograms using the specified method ( -:math:`H_1` -denotes the first histogram, -:math:`H_2` -the second): - - - - - -* Correlation (method=CV\_COMP\_CORREL) - - - .. math:: - - d(H_1,H_2) = \frac{\sum_I (H'_1(I) \cdot H'_2(I))}{\sqrt{\sum_I(H'_1(I)^2) \cdot \sum_I(H'_2(I)^2)}} - - - where - - - .. math:: - - H'_k(I) = \frac{H_k(I) - 1}{N \cdot \sum_J H_k(J)} - - - where N is the number of histogram bins. - - - -* Chi-Square (method=CV\_COMP\_CHISQR) - - - .. math:: - - d(H_1,H_2) = \sum _I \frac{(H_1(I)-H_2(I))^2}{H_1(I)+H_2(I)} - - - - -* Intersection (method=CV\_COMP\_INTERSECT) - - - .. math:: - - d(H_1,H_2) = \sum _I \min (H_1(I), H_2(I)) - - - - -* Bhattacharyya distance (method=CV\_COMP\_BHATTACHARYYA) - - - .. math:: - - d(H_1,H_2) = \sqrt{1 - \sum_I \frac{\sqrt{H_1(I) \cdot H_2(I)}}{ \sqrt{ \sum_I H_1(I) \cdot \sum_I H_2(I) }}} - - - - -The function returns -:math:`d(H_1, H_2)` -. - -Note: the method -``CV_COMP_BHATTACHARYYA`` -only works with normalized histograms. - -To compare a sparse histogram or more general sparse configurations of weighted points, consider using the -:ref:`CalcEMD2` -function. - - -.. index:: CopyHist - -.. _CopyHist: - -CopyHist --------- - - - - - - -.. cfunction:: void cvCopyHist( const CvHistogram* src, CvHistogram** dst ) - - Copies a histogram. - - - - - - - :param src: Source histogram - - - :param dst: Pointer to destination histogram - - - -The function makes a copy of the histogram. If the -second histogram pointer -``*dst`` -is NULL, a new histogram of the -same size as -``src`` -is created. Otherwise, both histograms must -have equal types and sizes. Then the function copies the source histogram's -bin values to the destination histogram and sets the same bin value ranges -as in -``src`` -. - - -.. index:: CreateHist - -.. _CreateHist: - -CreateHist ----------- - - - - - - -.. cfunction:: CvHistogram* cvCreateHist( int dims, int* sizes, int type, float** ranges=NULL, int uniform=1 ) - - Creates a histogram. - - - - - - - :param dims: Number of histogram dimensions - - :param sizes: Array of the histogram dimension sizes - - - :param type: Histogram representation format: ``CV_HIST_ARRAY`` means that the histogram data is represented as a multi-dimensional dense array CvMatND; ``CV_HIST_SPARSE`` means that histogram data is represented as a multi-dimensional sparse array CvSparseMat - - - :param ranges: Array of ranges for the histogram bins. Its meaning depends on the ``uniform`` parameter value. The ranges are used for when the histogram is calculated or backprojected to determine which histogram bin corresponds to which value/tuple of values from the input image(s) - - - :param uniform: Uniformity flag; if not 0, the histogram has evenly - spaced bins and for every :math:`0<=ibins, (idx0), 0 )) - #define cvGetHistValue_2D( hist, idx0, idx1 ) - ((float*)(cvPtr2D( (hist)->bins, (idx0), (idx1), 0 ))) - #define cvGetHistValue_3D( hist, idx0, idx1, idx2 ) - ((float*)(cvPtr3D( (hist)->bins, (idx0), (idx1), (idx2), 0 ))) - #define cvGetHistValue_nD( hist, idx ) - ((float*)(cvPtrND( (hist)->bins, (idx), 0 ))) - - -.. - -The macros -``GetHistValue`` -return a pointer to the specified bin of the 1D, 2D, 3D or N-D histogram. In the case of a sparse histogram the function creates a new bin and sets it to 0, unless it exists already. - -.. index:: GetMinMaxHistValue - -.. _GetMinMaxHistValue: - -GetMinMaxHistValue ------------------- - - - - - - -.. cfunction:: void cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value, int* min_idx=NULL, int* max_idx=NULL ) - - Finds the minimum and maximum histogram bins. - - - - - - - :param hist: Histogram - - - :param min_value: Pointer to the minimum value of the histogram - - - :param max_value: Pointer to the maximum value of the histogram - - - :param min_idx: Pointer to the array of coordinates for the minimum - - - :param max_idx: Pointer to the array of coordinates for the maximum - - - -The function finds the minimum and -maximum histogram bins and their positions. All of output arguments are -optional. Among several extremas with the same value the ones with the -minimum index (in lexicographical order) are returned. In the case of several maximums -or minimums, the earliest in lexicographical order (extrema locations) -is returned. - - -.. index:: MakeHistHeaderForArray - -.. _MakeHistHeaderForArray: - -MakeHistHeaderForArray ----------------------- - - - - - - -.. cfunction:: CvHistogram* cvMakeHistHeaderForArray( int dims, int* sizes, CvHistogram* hist, float* data, float** ranges=NULL, int uniform=1 ) - - Makes a histogram out of an array. - - - - - - - :param dims: Number of histogram dimensions - - - :param sizes: Array of the histogram dimension sizes - - - :param hist: The histogram header initialized by the function - - - :param data: Array that will be used to store histogram bins - - - :param ranges: Histogram bin ranges, see :ref:`CreateHist` - - - :param uniform: Uniformity flag, see :ref:`CreateHist` - - - -The function initializes the histogram, whose header and bins are allocated by th user. -:ref:`ReleaseHist` -does not need to be called afterwards. Only dense histograms can be initialized this way. The function returns -``hist`` -. - -.. index:: NormalizeHist - -.. _NormalizeHist: - -NormalizeHist -------------- - - - - - - -.. cfunction:: void cvNormalizeHist( CvHistogram* hist, double factor ) - - Normalizes the histogram. - - - - - - - :param hist: Pointer to the histogram - - - :param factor: Normalization factor - - - -The function normalizes the histogram bins by scaling them, such that the sum of the bins becomes equal to -``factor`` -. - - -.. index:: QueryHistValue*D - -.. _QueryHistValue*D: - -QueryHistValue*D ----------------- - - - - - - -.. cfunction:: float QueryHistValue_1D(CvHistogram hist, int idx0) - - Queries the value of the histogram bin. - - - - - - - :param hist: Histogram - - - :param idx0, idx1, idx2, idx3: Indices of the bin - - - :param idx: Array of indices - - - - - - -:: - - - - #define cvQueryHistValue_1D( hist, idx0 ) \ - cvGetReal1D( (hist)->bins, (idx0) ) - #define cvQueryHistValue_2D( hist, idx0, idx1 ) \ - cvGetReal2D( (hist)->bins, (idx0), (idx1) ) - #define cvQueryHistValue_3D( hist, idx0, idx1, idx2 ) \ - cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2) ) - #define cvQueryHistValue_nD( hist, idx ) \ - cvGetRealND( (hist)->bins, (idx) ) - - -.. - -The macros return the value of the specified bin of the 1D, 2D, 3D or N-D histogram. In the case of a sparse histogram the function returns 0, if the bin is not present in the histogram no new bin is created. - -.. index:: ReleaseHist - -.. _ReleaseHist: - -ReleaseHist ------------ - - - - - - -.. cfunction:: void cvReleaseHist( CvHistogram** hist ) - - Releases the histogram. - - - - - - - :param hist: Double pointer to the released histogram - - - -The function releases the histogram (header and the data). The pointer to the histogram is cleared by the function. If -``*hist`` -pointer is already -``NULL`` -, the function does nothing. - - -.. index:: SetHistBinRanges - -.. _SetHistBinRanges: - -SetHistBinRanges ----------------- - - - - - - -.. cfunction:: void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform=1 ) - - Sets the bounds of the histogram bins. - - - - - - - :param hist: Histogram - - - :param ranges: Array of bin ranges arrays, see :ref:`CreateHist` - - - :param uniform: Uniformity flag, see :ref:`CreateHist` - - - -The function is a stand-alone function for setting bin ranges in the histogram. For a more detailed description of the parameters -``ranges`` -and -``uniform`` -see the -:ref:`CalcHist` -function, that can initialize the ranges as well. Ranges for the histogram bins must be set before the histogram is calculated or the backproject of the histogram is calculated. - - -.. index:: ThreshHist - -.. _ThreshHist: - -ThreshHist ----------- - - - - - - -.. cfunction:: void cvThreshHist( CvHistogram* hist, double threshold ) - - Thresholds the histogram. - - - - - - - :param hist: Pointer to the histogram - - - :param threshold: Threshold level - - - -The function clears histogram bins that are below the specified threshold. - diff --git a/doc/opencv1/c/imgproc_image_filtering.rst b/doc/opencv1/c/imgproc_image_filtering.rst deleted file mode 100644 index c03cf5058d..0000000000 --- a/doc/opencv1/c/imgproc_image_filtering.rst +++ /dev/null @@ -1,681 +0,0 @@ -Image Filtering -=============== - -.. highlight:: c - - -Functions and classes described in this section are used to perform various linear or non-linear filtering operations on 2D images (represented as -:cpp:func:`Mat` -'s), that is, for each pixel location -:math:`(x,y)` -in the source image some its (normally rectangular) neighborhood is considered and used to compute the response. In case of a linear filter it is a weighted sum of pixel values, in case of morphological operations it is the minimum or maximum etc. The computed response is stored to the destination image at the same location -:math:`(x,y)` -. It means, that the output image will be of the same size as the input image. Normally, the functions supports multi-channel arrays, in which case every channel is processed independently, therefore the output image will also have the same number of channels as the input one. - -Another common feature of the functions and classes described in this section is that, unlike simple arithmetic functions, they need to extrapolate values of some non-existing pixels. For example, if we want to smooth an image using a Gaussian -:math:`3 \times 3` -filter, then during the processing of the left-most pixels in each row we need pixels to the left of them, i.e. outside of the image. We can let those pixels be the same as the left-most image pixels (i.e. use "replicated border" extrapolation method), or assume that all the non-existing pixels are zeros ("contant border" extrapolation method) etc. - -.. index:: IplConvKernel - -.. _IplConvKernel: - -IplConvKernel -------------- - - - -.. ctype:: IplConvKernel - - - -An IplConvKernel is a rectangular convolution kernel, created by function -:ref:`CreateStructuringElementEx` -. - - -.. index:: CopyMakeBorder - -.. _CopyMakeBorder: - -CopyMakeBorder --------------- - - - - - - -.. cfunction:: void cvCopyMakeBorder( const CvArr* src, CvArr* dst, CvPoint offset, int bordertype, CvScalar value=cvScalarAll(0) ) - - Copies an image and makes a border around it. - - - - - - - :param src: The source image - - - :param dst: The destination image - - - :param offset: Coordinates of the top-left corner (or bottom-left in the case of images with bottom-left origin) of the destination image rectangle where the source image (or its ROI) is copied. Size of the rectanlge matches the source image size/ROI size - - - :param bordertype: Type of the border to create around the copied source image rectangle; types include: - - * **IPL_BORDER_CONSTANT** border is filled with the fixed value, passed as last parameter of the function. - - * **IPL_BORDER_REPLICATE** the pixels from the top and bottom rows, the left-most and right-most columns are replicated to fill the border. - - - (The other two border types from IPL, ``IPL_BORDER_REFLECT`` and ``IPL_BORDER_WRAP`` , are currently unsupported) - - - :param value: Value of the border pixels if ``bordertype`` is ``IPL_BORDER_CONSTANT`` - - - -The function copies the source 2D array into the interior of the destination array and makes a border of the specified type around the copied area. The function is useful when one needs to emulate border type that is different from the one embedded into a specific algorithm implementation. For example, morphological functions, as well as most of other filtering functions in OpenCV, internally use replication border type, while the user may need a zero border or a border, filled with 1's or 255's. - - -.. index:: CreateStructuringElementEx - -.. _CreateStructuringElementEx: - -CreateStructuringElementEx --------------------------- - - - - - - -.. cfunction:: IplConvKernel* cvCreateStructuringElementEx( int cols, int rows, int anchorX, int anchorY, int shape, int* values=NULL ) - - Creates a structuring element. - - - - - - - :param cols: Number of columns in the structuring element - - - :param rows: Number of rows in the structuring element - - - :param anchorX: Relative horizontal offset of the anchor point - - - :param anchorY: Relative vertical offset of the anchor point - - - :param shape: Shape of the structuring element; may have the following values: - - - * **CV_SHAPE_RECT** a rectangular element - - - * **CV_SHAPE_CROSS** a cross-shaped element - - - * **CV_SHAPE_ELLIPSE** an elliptic element - - - * **CV_SHAPE_CUSTOM** a user-defined element. In this case the parameter ``values`` specifies the mask, that is, which neighbors of the pixel must be considered - - - - - :param values: Pointer to the structuring element data, a plane array, representing row-by-row scanning of the element matrix. Non-zero values indicate points that belong to the element. If the pointer is ``NULL`` , then all values are considered non-zero, that is, the element is of a rectangular shape. This parameter is considered only if the shape is ``CV_SHAPE_CUSTOM`` - - - -The function CreateStructuringElementEx allocates and fills the structure -``IplConvKernel`` -, which can be used as a structuring element in the morphological operations. - - -.. index:: Dilate - -.. _Dilate: - -Dilate ------- - - -.. cfunction:: void cvDilate( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1 ) - - Dilates an image by using a specific structuring element. - - :param src: Source image - - :param dst: Destination image - - :param element: Structuring element used for dilation. If it is ``NULL``, a ``3 x 3`` rectangular structuring element is used - - :param iterations: Number of times dilation is applied - - -The function dilates the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the maximum is taken: - - -.. math:: - - \max _{(x',y') \, in \, \texttt{element} }src(x+x',y+y') - - -The function supports the in-place mode. Dilation can be applied several (``iterations``) times. For color images, each channel is processed independently. - - -.. index:: Erode - -.. _Erode: - -Erode ------ - - - - - - -.. cfunction:: void cvErode( const CvArr* src, CvArr* dst, IplConvKernel* element=NULL, int iterations=1) - - Erodes an image by using a specific structuring element. - - - :param src: Source image - - :param dst: Destination image - - :param element: Structuring element used for erosion. If it is ``NULL`` , a ``3 x 3`` rectangular structuring element is used - - :param iterations: Number of times erosion is applied - -The function erodes the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the minimum is taken: - - -.. math:: - - \min _{(x',y') \, in \, \texttt{element} }src(x+x',y+y') - - -The function supports the in-place mode. Erosion can be applied several (``iterations``) times. For color images, each channel is processed independently. - - -.. index:: Filter2D - -.. _Filter2D: - -Filter2D --------- - - - - - - -.. cfunction:: void cvFilter2D( const CvArr* src, CvArr* dst, const CvMat* kernel, CvPoint anchor=cvPoint(-1,-1)) - - Convolves an image with the kernel. - - - - - - - :param src: The source image - - - :param dst: The destination image - - - :param kernel: Convolution kernel, a single-channel floating point matrix. If you want to apply different kernels to different channels, split the image into separate color planes using :ref:`Split` and process them individually - - - :param anchor: The anchor of the kernel that indicates the relative position of a filtered point within the kernel. The anchor shoud lie within the kernel. The special default value (-1,-1) means that it is at the kernel center - - - -The function applies an arbitrary linear filter to the image. In-place operation is supported. When the aperture is partially outside the image, the function interpolates outlier pixel values from the nearest pixels that are inside the image. - - -.. index:: Laplace - -.. _Laplace: - -Laplace -------- - - - - - - -.. cfunction:: void cvLaplace( const CvArr* src, CvArr* dst, int apertureSize=3) - - Calculates the Laplacian of an image. - - - - - - - :param src: Source image - - - :param dst: Destination image - - - :param apertureSize: Aperture size (it has the same meaning as :ref:`Sobel` ) - - - -The function calculates the Laplacian of the source image by adding up the second x and y derivatives calculated using the Sobel operator: - - - -.. math:: - - \texttt{dst} (x,y) = \frac{d^2 \texttt{src}}{dx^2} + \frac{d^2 \texttt{src}}{dy^2} - - -Setting -``apertureSize`` -= 1 gives the fastest variant that is equal to convolving the image with the following kernel: - - - -.. math:: - - \vecthreethree {0}{1}{0}{1}{-4}{1}{0}{1}{0} - - -Similar to the -:ref:`Sobel` -function, no scaling is done and the same combinations of input and output formats are supported. - - -.. index:: MorphologyEx - -.. _MorphologyEx: - -MorphologyEx ------------- - - - - - - -.. cfunction:: void cvMorphologyEx( const CvArr* src, CvArr* dst, CvArr* temp, IplConvKernel* element, int operation, int iterations=1 ) - - Performs advanced morphological transformations. - - - - - - - :param src: Source image - - - :param dst: Destination image - - - :param temp: Temporary image, required in some cases - - - :param element: Structuring element - - - :param operation: Type of morphological operation, one of the following: - - * **CV_MOP_OPEN** opening - - * **CV_MOP_CLOSE** closing - - * **CV_MOP_GRADIENT** morphological gradient - - * **CV_MOP_TOPHAT** "top hat" - - * **CV_MOP_BLACKHAT** "black hat" - - - - - :param iterations: Number of times erosion and dilation are applied - - - -The function can perform advanced morphological transformations using erosion and dilation as basic operations. - -Opening: - - - -.. math:: - - dst=open(src,element)=dilate(erode(src,element),element) - - -Closing: - - - -.. math:: - - dst=close(src,element)=erode(dilate(src,element),element) - - -Morphological gradient: - - - -.. math:: - - dst=morph \_ grad(src,element)=dilate(src,element)-erode(src,element) - - -"Top hat": - - - -.. math:: - - dst=tophat(src,element)=src-open(src,element) - - -"Black hat": - - - -.. math:: - - dst=blackhat(src,element)=close(src,element)-src - - -The temporary image -``temp`` -is required for a morphological gradient and, in the case of in-place operation, for "top hat" and "black hat". - - -.. index:: PyrDown - -.. _PyrDown: - -PyrDown -------- - - - - - - -.. cfunction:: void cvPyrDown( const CvArr* src, CvArr* dst, int filter=CV_GAUSSIAN_5x5 ) - - Downsamples an image. - - - - - - - :param src: The source image - - - :param dst: The destination image, should have a half as large width and height than the source - - - :param filter: Type of the filter used for convolution; only ``CV_GAUSSIAN_5x5`` is currently supported - - - -The function performs the downsampling step of the Gaussian pyramid decomposition. First it convolves the source image with the specified filter and then downsamples the image by rejecting even rows and columns. - - -.. index:: ReleaseStructuringElement - -.. _ReleaseStructuringElement: - -ReleaseStructuringElement -------------------------- - - - - - - -.. cfunction:: void cvReleaseStructuringElement( IplConvKernel** element ) - - Deletes a structuring element. - - - - - - - :param element: Pointer to the deleted structuring element - - - -The function releases the structure -``IplConvKernel`` -that is no longer needed. If -``*element`` -is -``NULL`` -, the function has no effect. - -.. index:: Smooth - -.. _Smooth: - -Smooth ------- - - - - - - -.. cfunction:: void cvSmooth( const CvArr* src, CvArr* dst, int smoothtype=CV_GAUSSIAN, int param1=3, int param2=0, double param3=0, double param4=0) - - Smooths the image in one of several ways. - - - - - - - :param src: The source image - - - :param dst: The destination image - - - :param smoothtype: Type of the smoothing: - - - * **CV_BLUR_NO_SCALE** linear convolution with :math:`\texttt{param1}\times\texttt{param2}` box kernel (all 1's). If you want to smooth different pixels with different-size box kernels, you can use the integral image that is computed using :ref:`Integral` - - - * **CV_BLUR** linear convolution with :math:`\texttt{param1}\times\texttt{param2}` box kernel (all 1's) with subsequent scaling by :math:`1/(\texttt{param1}\cdot\texttt{param2})` - - - * **CV_GAUSSIAN** linear convolution with a :math:`\texttt{param1}\times\texttt{param2}` Gaussian kernel - - - * **CV_MEDIAN** median filter with a :math:`\texttt{param1}\times\texttt{param1}` square aperture - - - * **CV_BILATERAL** bilateral filter with a :math:`\texttt{param1}\times\texttt{param1}` square aperture, color sigma= ``param3`` and spatial sigma= ``param4`` . If ``param1=0`` , the aperture square side is set to ``cvRound(param4*1.5)*2+1`` . Information about bilateral filtering can be found at http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/MANDUCHI1/Bilateral\_Filtering.html - - - - - :param param1: The first parameter of the smoothing operation, the aperture width. Must be a positive odd number (1, 3, 5, ...) - - - :param param2: The second parameter of the smoothing operation, the aperture height. Ignored by ``CV_MEDIAN`` and ``CV_BILATERAL`` methods. In the case of simple scaled/non-scaled and Gaussian blur if ``param2`` is zero, it is set to ``param1`` . Otherwise it must be a positive odd number. - - - :param param3: In the case of a Gaussian parameter this parameter may specify Gaussian :math:`\sigma` (standard deviation). If it is zero, it is calculated from the kernel size: - - .. math:: - - \sigma = 0.3 (n/2 - 1) + 0.8 \quad \text{where} \quad n= \begin{array}{l l} \mbox{\texttt{param1} for horizontal kernel} \\ \mbox{\texttt{param2} for vertical kernel} \end{array} - - Using standard sigma for small kernels ( :math:`3\times 3` to :math:`7\times 7` ) gives better speed. If ``param3`` is not zero, while ``param1`` and ``param2`` are zeros, the kernel size is calculated from the sigma (to provide accurate enough operation). - - - -The function smooths an image using one of several methods. Every of the methods has some features and restrictions listed below - -Blur with no scaling works with single-channel images only and supports accumulation of 8-bit to 16-bit format (similar to -:ref:`Sobel` -and -:ref:`Laplace` -) and 32-bit floating point to 32-bit floating-point format. - -Simple blur and Gaussian blur support 1- or 3-channel, 8-bit and 32-bit floating point images. These two methods can process images in-place. - -Median and bilateral filters work with 1- or 3-channel 8-bit images and can not process images in-place. - - -.. index:: Sobel - -.. _Sobel: - -Sobel ------ - - - - - - -.. cfunction:: void cvSobel( const CvArr* src, CvArr* dst, int xorder, int yorder, int apertureSize=3 ) - - Calculates the first, second, third or mixed image derivatives using an extended Sobel operator. - - - - - - - :param src: Source image of type CvArr* - - - :param dst: Destination image - - - :param xorder: Order of the derivative x - - - :param yorder: Order of the derivative y - - - :param apertureSize: Size of the extended Sobel kernel, must be 1, 3, 5 or 7 - - - -In all cases except 1, an -:math:`\texttt{apertureSize} \times -\texttt{apertureSize}` -separable kernel will be used to calculate the -derivative. For -:math:`\texttt{apertureSize} = 1` -a -:math:`3 \times 1` -or -:math:`1 \times 3` -a kernel is used (Gaussian smoothing is not done). There is also the special -value -``CV_SCHARR`` -(-1) that corresponds to a -:math:`3\times3` -Scharr -filter that may give more accurate results than a -:math:`3\times3` -Sobel. Scharr -aperture is - - - -.. math:: - - \vecthreethree{-3}{0}{3}{-10}{0}{10}{-3}{0}{3} - - -for the x-derivative or transposed for the y-derivative. - -The function calculates the image derivative by convolving the image with the appropriate kernel: - - - -.. math:: - - \texttt{dst} (x,y) = \frac{d^{xorder+yorder} \texttt{src}}{dx^{xorder} \cdot dy^{yorder}} - - -The Sobel operators combine Gaussian smoothing and differentiation -so the result is more or less resistant to the noise. Most often, -the function is called with ( -``xorder`` -= 1, -``yorder`` -= 0, -``apertureSize`` -= 3) or ( -``xorder`` -= 0, -``yorder`` -= 1, -``apertureSize`` -= 3) to calculate the first x- or y- image -derivative. The first case corresponds to a kernel of: - - - -.. math:: - - \vecthreethree{-1}{0}{1}{-2}{0}{2}{-1}{0}{1} - - -and the second one corresponds to a kernel of: - - -.. math:: - - \vecthreethree{-1}{-2}{-1}{0}{0}{0}{1}{2}{1} - - -or a kernel of: - - -.. math:: - - \vecthreethree{1}{2}{1}{0}{0}{0}{-1}{2}{-1} - - -depending on the image origin ( -``origin`` -field of -``IplImage`` -structure). No scaling is done, so the destination image -usually has larger numbers (in absolute values) than the source image does. To -avoid overflow, the function requires a 16-bit destination image if the -source image is 8-bit. The result can be converted back to 8-bit using the -:ref:`ConvertScale` -or the -:ref:`ConvertScaleAbs` -function. Besides 8-bit images -the function can process 32-bit floating-point images. Both the source and the -destination must be single-channel images of equal size or equal ROI size. - diff --git a/doc/opencv1/c/imgproc_miscellaneous_image_transformations.rst b/doc/opencv1/c/imgproc_miscellaneous_image_transformations.rst deleted file mode 100644 index bc031b1d0b..0000000000 --- a/doc/opencv1/c/imgproc_miscellaneous_image_transformations.rst +++ /dev/null @@ -1,1404 +0,0 @@ -Miscellaneous Image Transformations -=================================== - -.. highlight:: c - - - -.. index:: AdaptiveThreshold - -.. _AdaptiveThreshold: - -AdaptiveThreshold ------------------ - - - - - - -.. cfunction:: void cvAdaptiveThreshold( const CvArr* src, CvArr* dst, double maxValue,int adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C,int thresholdType=CV_THRESH_BINARY,int blockSize=3, double param1=5 ) - - Applies an adaptive threshold to an array. - - - - - - - :param src: Source image - - - :param dst: Destination image - - - :param maxValue: Maximum value that is used with ``CV_THRESH_BINARY`` and ``CV_THRESH_BINARY_INV`` - - - :param adaptive_method: Adaptive thresholding algorithm to use: ``CV_ADAPTIVE_THRESH_MEAN_C`` or ``CV_ADAPTIVE_THRESH_GAUSSIAN_C`` (see the discussion) - - - :param thresholdType: Thresholding type; must be one of - - * **CV_THRESH_BINARY** xxx - - * **CV_THRESH_BINARY_INV** xxx - - - - - :param blockSize: The size of a pixel neighborhood that is used to calculate a threshold value for the pixel: 3, 5, 7, and so on - - - :param param1: The method-dependent parameter. For the methods ``CV_ADAPTIVE_THRESH_MEAN_C`` and ``CV_ADAPTIVE_THRESH_GAUSSIAN_C`` it is a constant subtracted from the mean or weighted mean (see the discussion), though it may be negative - - - -The function transforms a grayscale image to a binary image according to the formulas: - - - - - * **CV_THRESH_BINARY** - - .. math:: - - dst(x,y) = \fork{\texttt{maxValue}}{if $src(x,y) > T(x,y)$}{0}{otherwise} - - - - - * **CV_THRESH_BINARY_INV** - - .. math:: - - dst(x,y) = \fork{0}{if $src(x,y) > T(x,y)$}{\texttt{maxValue}}{otherwise} - - - - - -where -:math:`T(x,y)` -is a threshold calculated individually for each pixel. - -For the method -``CV_ADAPTIVE_THRESH_MEAN_C`` -it is the mean of a -:math:`\texttt{blockSize} \times \texttt{blockSize}` -pixel neighborhood, minus -``param1`` -. - -For the method -``CV_ADAPTIVE_THRESH_GAUSSIAN_C`` -it is the weighted sum (gaussian) of a -:math:`\texttt{blockSize} \times \texttt{blockSize}` -pixel neighborhood, minus -``param1`` -. - - -.. index:: CvtColor - -.. _CvtColor: - -CvtColor --------- - - - - - - -.. cfunction:: void cvCvtColor( const CvArr* src, CvArr* dst, int code ) - - Converts an image from one color space to another. - - - - - - - :param src: The source 8-bit (8u), 16-bit (16u) or single-precision floating-point (32f) image - - - :param dst: The destination image of the same data type as the source. The number of channels may be different - - - :param code: Color conversion operation that can be specifed using ``CV_ *src_color_space* 2 *dst_color_space*`` constants (see below) - - - -The function converts the input image from one color -space to another. The function ignores the -``colorModel`` -and -``channelSeq`` -fields of the -``IplImage`` -header, so the -source image color space should be specified correctly (including -order of the channels in the case of RGB space. For example, BGR means 24-bit -format with -:math:`B_0, G_0, R_0, B_1, G_1, R_1, ...` -layout -whereas RGB means 24-format with -:math:`R_0, G_0, B_0, R_1, G_1, B_1, ...` -layout). - -The conventional range for R,G,B channel values is: - - - - - -* - 0 to 255 for 8-bit images - - -* - 0 to 65535 for 16-bit images and - - -* - 0 to 1 for floating-point images. - - -Of course, in the case of linear transformations the range can be -specific, but in order to get correct results in the case of non-linear -transformations, the input image should be scaled. - -The function can do the following transformations: - - - - - -* - Transformations within RGB space like adding/removing the alpha channel, reversing the channel order, conversion to/from 16-bit RGB color (R5:G6:B5 or R5:G5:B5), as well as conversion to/from grayscale using: - - - .. math:: - - \text{RGB[A] to Gray:} Y \leftarrow 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B - - - and - - - .. math:: - - \text{Gray to RGB[A]:} R \leftarrow Y, G \leftarrow Y, B \leftarrow Y, A \leftarrow 0 - - - The conversion from a RGB image to gray is done with: - - - - :: - - - - cvCvtColor(src ,bwsrc, CV_RGB2GRAY) - - - .. - - - -* - RGB - :math:`\leftrightarrow` - CIE XYZ.Rec 709 with D65 white point ( - ``CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB`` - ): - - - .. math:: - - \begin{bmatrix} X \\ Y \\ Z \end{bmatrix} \leftarrow \begin{bmatrix} 0.412453 & 0.357580 & 0.180423 \\ 0.212671 & 0.715160 & 0.072169 \\ 0.019334 & 0.119193 & 0.950227 \end{bmatrix} \cdot \begin{bmatrix} R \\ G \\ B \end{bmatrix} - - - - - .. math:: - - \begin{bmatrix} R \\ G \\ B \end{bmatrix} \leftarrow \begin{bmatrix} 3.240479 & -1.53715 & -0.498535 \\ -0.969256 & 1.875991 & 0.041556 \\ 0.055648 & -0.204043 & 1.057311 \end{bmatrix} \cdot \begin{bmatrix} X \\ Y \\ Z \end{bmatrix} - - - :math:`X` - , - :math:`Y` - and - :math:`Z` - cover the whole value range (in the case of floating-point images - :math:`Z` - may exceed 1). - - - -* - RGB - :math:`\leftrightarrow` - YCrCb JPEG (a.k.a. YCC) ( - ``CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB`` - ) - - - .. math:: - - Y \leftarrow 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B - - - - - .. math:: - - Cr \leftarrow (R-Y) \cdot 0.713 + delta - - - - - .. math:: - - Cb \leftarrow (B-Y) \cdot 0.564 + delta - - - - - .. math:: - - R \leftarrow Y + 1.403 \cdot (Cr - delta) - - - - - .. math:: - - G \leftarrow Y - 0.344 \cdot (Cr - delta) - 0.714 \cdot (Cb - delta) - - - - - .. math:: - - B \leftarrow Y + 1.773 \cdot (Cb - delta) - - - where - - - .. math:: - - delta = \left \{ \begin{array}{l l} 128 & \mbox{for 8-bit images} \\ 32768 & \mbox{for 16-bit images} \\ 0.5 & \mbox{for floating-point images} \end{array} \right . - - - Y, Cr and Cb cover the whole value range. - - - -* - RGB - :math:`\leftrightarrow` - HSV ( - ``CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB`` - ) - in the case of 8-bit and 16-bit images - R, G and B are converted to floating-point format and scaled to fit the 0 to 1 range - - - .. math:: - - V \leftarrow max(R,G,B) - - - - - .. math:: - - S \leftarrow \fork{\frac{V-min(R,G,B)}{V}}{if $V \neq 0$}{0}{otherwise} - - - - - .. math:: - - H \leftarrow \forkthree{{60(G - B)}/{S}}{if $V=R$}{{120+60(B - R)}/{S}}{if $V=G$}{{240+60(R - G)}/{S}}{if $V=B$} - - - if - :math:`H<0` - then - :math:`H \leftarrow H+360` - On output - :math:`0 \leq V \leq 1` - , - :math:`0 \leq S \leq 1` - , - :math:`0 \leq H \leq 360` - . - - The values are then converted to the destination data type: - - - - - * 8-bit images - - - .. math:: - - V \leftarrow 255 V, S \leftarrow 255 S, H \leftarrow H/2 \text{(to fit to 0 to 255)} - - - - - * 16-bit images (currently not supported) - - - .. math:: - - V <- 65535 V, S <- 65535 S, H <- H - - - - - * 32-bit images - H, S, V are left as is - - - - -* - RGB - :math:`\leftrightarrow` - HLS ( - ``CV_BGR2HLS, CV_RGB2HLS, CV_HLS2BGR, CV_HLS2RGB`` - ). - in the case of 8-bit and 16-bit images - R, G and B are converted to floating-point format and scaled to fit the 0 to 1 range. - - - .. math:: - - V_{max} \leftarrow {max}(R,G,B) - - - - - .. math:: - - V_{min} \leftarrow {min}(R,G,B) - - - - - .. math:: - - L \leftarrow \frac{V_{max} + V_{min}}{2} - - - - - .. math:: - - S \leftarrow \fork{\frac{V_{max} - V_{min}}{V_{max} + V_{min}}}{if $L < 0.5$}{\frac{V_{max} - V_{min}}{2 - (V_{max} + V_{min})}}{if $L \ge 0.5$} - - - - - .. math:: - - H \leftarrow \forkthree{{60(G - B)}/{S}}{if $V_{max}=R$}{{120+60(B - R)}/{S}}{if $V_{max}=G$}{{240+60(R - G)}/{S}}{if $V_{max}=B$} - - - if - :math:`H<0` - then - :math:`H \leftarrow H+360` - On output - :math:`0 \leq L \leq 1` - , - :math:`0 \leq S \leq 1` - , - :math:`0 \leq H \leq 360` - . - - The values are then converted to the destination data type: - - - - - * 8-bit images - - - .. math:: - - V \leftarrow 255 V, S \leftarrow 255 S, H \leftarrow H/2 \text{(to fit to 0 to 255)} - - - - - * 16-bit images (currently not supported) - - - .. math:: - - V <- 65535 V, S <- 65535 S, H <- H - - - - - * 32-bit images - H, S, V are left as is - - - - -* - RGB - :math:`\leftrightarrow` - CIE L*a*b* ( - ``CV_BGR2Lab, CV_RGB2Lab, CV_Lab2BGR, CV_Lab2RGB`` - ) - in the case of 8-bit and 16-bit images - R, G and B are converted to floating-point format and scaled to fit the 0 to 1 range - - - .. math:: - - \vecthree{X}{Y}{Z} \leftarrow \vecthreethree{0.412453}{0.357580}{0.180423}{0.212671}{0.715160}{0.072169}{0.019334}{0.119193}{0.950227} \cdot \vecthree{R}{G}{B} - - - - - .. math:: - - X \leftarrow X/X_n, \text{where} X_n = 0.950456 - - - - - .. math:: - - Z \leftarrow Z/Z_n, \text{where} Z_n = 1.088754 - - - - - .. math:: - - L \leftarrow \fork{116*Y^{1/3}-16}{for $Y>0.008856$}{903.3*Y}{for $Y \le 0.008856$} - - - - - .. math:: - - a \leftarrow 500 (f(X)-f(Y)) + delta - - - - - .. math:: - - b \leftarrow 200 (f(Y)-f(Z)) + delta - - - where - - - .. math:: - - f(t)= \fork{t^{1/3}}{for $t>0.008856$}{7.787 t+16/116}{for $t<=0.008856$} - - - and - - - .. math:: - - delta = \fork{128}{for 8-bit images}{0}{for floating-point images} - - - On output - :math:`0 \leq L \leq 100` - , - :math:`-127 \leq a \leq 127` - , - :math:`-127 \leq b \leq 127` - The values are then converted to the destination data type: - - - - - * 8-bit images - - - .. math:: - - L \leftarrow L*255/100, a \leftarrow a + 128, b \leftarrow b + 128 - - - - - * 16-bit images - currently not supported - - - * 32-bit images - L, a, b are left as is - - - - -* - RGB - :math:`\leftrightarrow` - CIE L*u*v* ( - ``CV_BGR2Luv, CV_RGB2Luv, CV_Luv2BGR, CV_Luv2RGB`` - ) - in the case of 8-bit and 16-bit images - R, G and B are converted to floating-point format and scaled to fit 0 to 1 range - - - .. math:: - - \vecthree{X}{Y}{Z} \leftarrow \vecthreethree{0.412453}{0.357580}{0.180423}{0.212671}{0.715160}{0.072169}{0.019334}{0.119193}{0.950227} \cdot \vecthree{R}{G}{B} - - - - - .. math:: - - L \leftarrow \fork{116 Y^{1/3}}{for $Y>0.008856$}{903.3 Y}{for $Y<=0.008856$} - - - - - .. math:: - - u' \leftarrow 4*X/(X + 15*Y + 3 Z) - - - - - .. math:: - - v' \leftarrow 9*Y/(X + 15*Y + 3 Z) - - - - - .. math:: - - u \leftarrow 13*L*(u' - u_n) \quad \text{where} \quad u_n=0.19793943 - - - - - .. math:: - - v \leftarrow 13*L*(v' - v_n) \quad \text{where} \quad v_n=0.46831096 - - - On output - :math:`0 \leq L \leq 100` - , - :math:`-134 \leq u \leq 220` - , - :math:`-140 \leq v \leq 122` - . - - The values are then converted to the destination data type: - - - - - * 8-bit images - - - .. math:: - - L \leftarrow 255/100 L, u \leftarrow 255/354 (u + 134), v \leftarrow 255/256 (v + 140) - - - - - * 16-bit images - currently not supported - - - * 32-bit images - L, u, v are left as is - - - The above formulas for converting RGB to/from various color spaces have been taken from multiple sources on Web, primarily from - the Ford98 - at the Charles Poynton site. - - - -* - Bayer - :math:`\rightarrow` - RGB ( - ``CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR, CV_BayerGR2BGR, CV_BayerBG2RGB, CV_BayerGB2RGB, CV_BayerRG2RGB, CV_BayerGR2RGB`` - ) The Bayer pattern is widely used in CCD and CMOS cameras. It allows one to get color pictures from a single plane where R,G and B pixels (sensors of a particular component) are interleaved like this: - - - .. image:: ../pics/bayer.png - - The output RGB components of a pixel are interpolated from 1, 2 or - 4 neighbors of the pixel having the same color. There are several - modifications of the above pattern that can be achieved by shifting - the pattern one pixel left and/or one pixel up. The two letters - :math:`C_1` - and - :math:`C_2` - in the conversion constants - ``CV_Bayer`` - :math:`C_1 C_2` - ``2BGR`` - and - ``CV_Bayer`` - :math:`C_1 C_2` - ``2RGB`` - indicate the particular pattern - type - these are components from the second row, second and third - columns, respectively. For example, the above pattern has very - popular "BG" type. - - - -.. index:: DistTransform - -.. _DistTransform: - -DistTransform -------------- - - - - - - -.. cfunction:: void cvDistTransform( const CvArr* src, CvArr* dst, int distance_type=CV_DIST_L2, int mask_size=3, const float* mask=NULL, CvArr* labels=NULL ) - - Calculates the distance to the closest zero pixel for all non-zero pixels of the source image. - - - - - - - :param src: 8-bit, single-channel (binary) source image - - - :param dst: Output image with calculated distances (32-bit floating-point, single-channel) - - - :param distance_type: Type of distance; can be ``CV_DIST_L1, CV_DIST_L2, CV_DIST_C`` or ``CV_DIST_USER`` - - - :param mask_size: Size of the distance transform mask; can be 3 or 5. in the case of ``CV_DIST_L1`` or ``CV_DIST_C`` the parameter is forced to 3, because a :math:`3\times 3` mask gives the same result as a :math:`5\times 5` yet it is faster - - - :param mask: User-defined mask in the case of a user-defined distance, it consists of 2 numbers (horizontal/vertical shift cost, diagonal shift cost) in the case ofa :math:`3\times 3` mask and 3 numbers (horizontal/vertical shift cost, diagonal shift cost, knight's move cost) in the case of a :math:`5\times 5` mask - - - :param labels: The optional output 2d array of integer type labels, the same size as ``src`` and ``dst`` - - - -The function calculates the approximated -distance from every binary image pixel to the nearest zero pixel. -For zero pixels the function sets the zero distance, for others it -finds the shortest path consisting of basic shifts: horizontal, -vertical, diagonal or knight's move (the latest is available for a -:math:`5\times 5` -mask). The overall distance is calculated as a sum of these -basic distances. Because the distance function should be symmetric, -all of the horizontal and vertical shifts must have the same cost (that -is denoted as -``a`` -), all the diagonal shifts must have the -same cost (denoted -``b`` -), and all knight's moves must have -the same cost (denoted -``c`` -). For -``CV_DIST_C`` -and -``CV_DIST_L1`` -types the distance is calculated precisely, -whereas for -``CV_DIST_L2`` -(Euclidian distance) the distance -can be calculated only with some relative error (a -:math:`5\times 5` -mask -gives more accurate results), OpenCV uses the values suggested in -Borgefors86 -: - - - -.. table:: - - ============== =================== ====================== - ``CV_DIST_C`` :math:`(3\times 3)` a = 1, b = 1 \ - ============== =================== ====================== - ``CV_DIST_L1`` :math:`(3\times 3)` a = 1, b = 2 \ - ``CV_DIST_L2`` :math:`(3\times 3)` a=0.955, b=1.3693 \ - ``CV_DIST_L2`` :math:`(5\times 5)` a=1, b=1.4, c=2.1969 \ - ============== =================== ====================== - -And below are samples of the distance field (black (0) pixel is in the middle of white square) in the case of a user-defined distance: - -User-defined -:math:`3 \times 3` -mask (a=1, b=1.5) - - -.. table:: - - === === === = === === ===== - 4.5 4 3.5 3 3.5 4 4.5 \ - === === === = === === ===== - 4 3 2.5 2 2.5 3 4 \ - 3.5 2.5 1.5 1 1.5 2.5 3.5 \ - 3 2 1 1 2 3 \ - 3.5 2.5 1.5 1 1.5 2.5 3.5 \ - 4 3 2.5 2 2.5 3 4 \ - 4.5 4 3.5 3 3.5 4 4.5 \ - === === === = === === ===== - -User-defined -:math:`5 \times 5` -mask (a=1, b=1.5, c=2) - - -.. table:: - - === === === = === === ===== - 4.5 3.5 3 3 3 3.5 4.5 \ - === === === = === === ===== - 3.5 3 2 2 2 3 3.5 \ - 3 2 1.5 1 1.5 2 3 \ - 3 2 1 1 2 3 \ - 3 2 1.5 1 1.5 2 3 \ - 3.5 3 2 2 2 3 3.5 \ - 4 3.5 3 3 3 3.5 4 \ - === === === = === === ===== - -Typically, for a fast, coarse distance estimation -``CV_DIST_L2`` -, -a -:math:`3\times 3` -mask is used, and for a more accurate distance estimation -``CV_DIST_L2`` -, a -:math:`5\times 5` -mask is used. - -When the output parameter -``labels`` -is not -``NULL`` -, for -every non-zero pixel the function also finds the nearest connected -component consisting of zero pixels. The connected components -themselves are found as contours in the beginning of the function. - -In this mode the processing time is still O(N), where N is the number of -pixels. Thus, the function provides a very fast way to compute approximate -Voronoi diagram for the binary image. - - -.. index:: CvConnectedComp - -.. _CvConnectedComp: - -CvConnectedComp ---------------- - - - -.. ctype:: CvConnectedComp - - - - - - -:: - - - - typedef struct CvConnectedComp - { - double area; /* area of the segmented component */ - CvScalar value; /* average color of the connected component */ - CvRect rect; /* ROI of the segmented component */ - CvSeq* contour; /* optional component boundary - (the contour might have child contours corresponding to the holes) */ - } CvConnectedComp; - - - -.. - - -.. index:: FloodFill - -.. _FloodFill: - -FloodFill ---------- - - - - - - -.. cfunction:: void cvFloodFill( CvArr* image, CvPoint seed_point, CvScalar new_val, CvScalar lo_diff=cvScalarAll(0), CvScalar up_diff=cvScalarAll(0), CvConnectedComp* comp=NULL, int flags=4, CvArr* mask=NULL ) - - Fills a connected component with the given color. - - - - - - - :param image: Input 1- or 3-channel, 8-bit or floating-point image. It is modified by the function unless the ``CV_FLOODFILL_MASK_ONLY`` flag is set (see below) - - - :param seed_point: The starting point - - - :param new_val: New value of the repainted domain pixels - - - :param lo_diff: Maximal lower brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component. In the case of 8-bit color images it is a packed value - - - :param up_diff: Maximal upper brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component. In the case of 8-bit color images it is a packed value - - - :param comp: Pointer to the structure that the function fills with the information about the repainted domain. - Note that the function does not fill ``comp->contour`` field. The boundary of the filled component can be retrieved from the output mask image using :ref:`FindContours` - - - :param flags: The operation flags. Lower bits contain connectivity value, 4 (by default) or 8, used within the function. Connectivity determines which neighbors of a pixel are considered. Upper bits can be 0 or a combination of the following flags: - - - * **CV_FLOODFILL_FIXED_RANGE** if set, the difference between the current pixel and seed pixel is considered, otherwise the difference between neighbor pixels is considered (the range is floating) - - - * **CV_FLOODFILL_MASK_ONLY** if set, the function does not fill the image ( ``new_val`` is ignored), but fills the mask (that must be non-NULL in this case) - - - - - :param mask: Operation mask, should be a single-channel 8-bit image, 2 pixels wider and 2 pixels taller than ``image`` . If not NULL, the function uses and updates the mask, so the user takes responsibility of initializing the ``mask`` content. Floodfilling can't go across non-zero pixels in the mask, for example, an edge detector output can be used as a mask to stop filling at edges. It is possible to use the same mask in multiple calls to the function to make sure the filled area do not overlap. **Note** : because the mask is larger than the filled image, a pixel in ``mask`` that corresponds to :math:`(x,y)` pixel in ``image`` will have coordinates :math:`(x+1,y+1)` - - - -The function fills a connected component starting from the seed point with the specified color. The connectivity is determined by the closeness of pixel values. The pixel at -:math:`(x,y)` -is considered to belong to the repainted domain if: - - - - - -* grayscale image, floating range - - - .. math:: - - src(x',y')- \texttt{lo\_diff} <= src(x,y) <= src(x',y')+ \texttt{up\_diff} - - - - -* grayscale image, fixed range - - - .. math:: - - src(seed.x,seed.y)- \texttt{lo\_diff} <=src(x,y)<=src(seed.x,seed.y)+ \texttt{up\_diff} - - - - -* color image, floating range - - - .. math:: - - src(x',y')_r- \texttt{lo\_diff} _r<=src(x,y)_r<=src(x',y')_r+ \texttt{up\_diff} _r - - - - - .. math:: - - src(x',y')_g- \texttt{lo\_diff} _g<=src(x,y)_g<=src(x',y')_g+ \texttt{up\_diff} _g - - - - - .. math:: - - src(x',y')_b- \texttt{lo\_diff} _b<=src(x,y)_b<=src(x',y')_b+ \texttt{up\_diff} _b - - - - -* color image, fixed range - - - .. math:: - - src(seed.x,seed.y)_r- \texttt{lo\_diff} _r<=src(x,y)_r<=src(seed.x,seed.y)_r+ \texttt{up\_diff} _r - - - - - .. math:: - - src(seed.x,seed.y)_g- \texttt{lo\_diff} _g<=src(x,y)_g<=src(seed.x,seed.y)_g+ \texttt{up\_diff} _g - - - - - .. math:: - - src(seed.x,seed.y)_b- \texttt{lo\_diff} _b<=src(x,y)_b<=src(seed.x,seed.y)_b+ \texttt{up\_diff} _b - - - - -where -:math:`src(x',y')` -is the value of one of pixel neighbors. That is, to be added to the connected component, a pixel's color/brightness should be close enough to the: - - - - -* - color/brightness of one of its neighbors that are already referred to the connected component in the case of floating range - - - -* - color/brightness of the seed point in the case of fixed range. - - - -.. index:: Inpaint - -.. _Inpaint: - -Inpaint -------- - - - - - - -.. cfunction:: void cvInpaint( const CvArr* src, const CvArr* mask, CvArr* dst, double inpaintRadius, int flags) - - Inpaints the selected region in the image. - - - - - - - :param src: The input 8-bit 1-channel or 3-channel image. - - - :param mask: The inpainting mask, 8-bit 1-channel image. Non-zero pixels indicate the area that needs to be inpainted. - - - :param dst: The output image of the same format and the same size as input. - - - :param inpaintRadius: The radius of circlular neighborhood of each point inpainted that is considered by the algorithm. - - - :param flags: The inpainting method, one of the following: - - * **CV_INPAINT_NS** Navier-Stokes based method. - - * **CV_INPAINT_TELEA** The method by Alexandru Telea Telea04 - - - - - -The function reconstructs the selected image area from the pixel near the area boundary. The function may be used to remove dust and scratches from a scanned photo, or to remove undesirable objects from still images or video. - - -.. index:: Integral - -.. _Integral: - -Integral --------- - - - - - - -.. cfunction:: void cvIntegral( const CvArr* image, CvArr* sum, CvArr* sqsum=NULL, CvArr* tiltedSum=NULL ) - - Calculates the integral of an image. - - - - - - - :param image: The source image, :math:`W\times H` , 8-bit or floating-point (32f or 64f) - - - :param sum: The integral image, :math:`(W+1)\times (H+1)` , 32-bit integer or double precision floating-point (64f) - - - :param sqsum: The integral image for squared pixel values, :math:`(W+1)\times (H+1)` , double precision floating-point (64f) - - - :param tiltedSum: The integral for the image rotated by 45 degrees, :math:`(W+1)\times (H+1)` , the same data type as ``sum`` - - - -The function calculates one or more integral images for the source image as following: - - - -.. math:: - - \texttt{sum} (X,Y) = \sum _{x0` -, the gaussian pyramid of -:math:`\texttt{max\_level}+1` -levels is built, and the above procedure is run -on the smallest layer. After that, the results are propagated to the -larger layer and the iterations are run again only on those pixels where -the layer colors differ much ( -:math:`>\texttt{sr}` -) from the lower-resolution -layer, that is, the boundaries of the color regions are clarified. Note, -that the results will be actually different from the ones obtained by -running the meanshift procedure on the whole original image (i.e. when -:math:`\texttt{max\_level}==0` -). - - -.. index:: PyrSegmentation - -.. _PyrSegmentation: - -PyrSegmentation ---------------- - - - - - - -.. cfunction:: void cvPyrSegmentation( IplImage* src, IplImage* dst, CvMemStorage* storage, CvSeq** comp, int level, double threshold1, double threshold2 ) - - Implements image segmentation by pyramids. - - - - - - - :param src: The source image - - - :param dst: The destination image - - - :param storage: Storage; stores the resulting sequence of connected components - - - :param comp: Pointer to the output sequence of the segmented components - - - :param level: Maximum level of the pyramid for the segmentation - - - :param threshold1: Error threshold for establishing the links - - - :param threshold2: Error threshold for the segments clustering - - - -The function implements image segmentation by pyramids. The pyramid builds up to the level -``level`` -. The links between any pixel -``a`` -on level -``i`` -and its candidate father pixel -``b`` -on the adjacent level are established if -:math:`p(c(a),c(b)) \texttt{threshold}$}{0}{otherwise} - - - - - * **CV_THRESH_BINARY_INV** - - .. math:: - - \texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{threshold}$}{\texttt{maxValue}}{otherwise} - - - - - * **CV_THRESH_TRUNC** - - .. math:: - - \texttt{dst} (x,y) = \fork{\texttt{threshold}}{if $\texttt{src}(x,y) > \texttt{threshold}$}{\texttt{src}(x,y)}{otherwise} - - - - - * **CV_THRESH_TOZERO** - - .. math:: - - \texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if $\texttt{src}(x,y) > \texttt{threshold}$}{0}{otherwise} - - - - - * **CV_THRESH_TOZERO_INV** - - .. math:: - - \texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{threshold}$}{\texttt{src}(x,y)}{otherwise} - - - - - -Also, the special value -``CV_THRESH_OTSU`` -may be combined with -one of the above values. In this case the function determines the optimal threshold -value using Otsu's algorithm and uses it instead of the specified -``thresh`` -. -The function returns the computed threshold value. -Currently, Otsu's method is implemented only for 8-bit images. - - - -.. image:: ../pics/threshold.png - - - diff --git a/doc/opencv1/c/imgproc_motion_analysis_and_object_tracking.rst b/doc/opencv1/c/imgproc_motion_analysis_and_object_tracking.rst deleted file mode 100644 index cbc755fb8d..0000000000 --- a/doc/opencv1/c/imgproc_motion_analysis_and_object_tracking.rst +++ /dev/null @@ -1,196 +0,0 @@ -Motion Analysis and Object Tracking -=================================== - -.. highlight:: c - - - -.. index:: Acc - -.. _Acc: - -Acc ---- - - - - - - -.. cfunction:: void cvAcc( const CvArr* image, CvArr* sum, const CvArr* mask=NULL ) - - Adds a frame to an accumulator. - - - - - - - :param image: Input image, 1- or 3-channel, 8-bit or 32-bit floating point. (each channel of multi-channel image is processed independently) - - - :param sum: Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point - - - :param mask: Optional operation mask - - - -The function adds the whole image -``image`` -or its selected region to the accumulator -``sum`` -: - - - -.. math:: - - \texttt{sum} (x,y) \leftarrow \texttt{sum} (x,y) + \texttt{image} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 - - - -.. index:: MultiplyAcc - -.. _MultiplyAcc: - -MultiplyAcc ------------ - - - - - - -.. cfunction:: void cvMultiplyAcc( const CvArr* image1, const CvArr* image2, CvArr* acc, const CvArr* mask=NULL ) - - Adds the product of two input images to the accumulator. - - - - - - - :param image1: First input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently) - - - :param image2: Second input image, the same format as the first one - - - :param acc: Accumulator with the same number of channels as input images, 32-bit or 64-bit floating-point - - - :param mask: Optional operation mask - - - -The function adds the product of 2 images or their selected regions to the accumulator -``acc`` -: - - - -.. math:: - - \texttt{acc} (x,y) \leftarrow \texttt{acc} (x,y) + \texttt{image1} (x,y) \cdot \texttt{image2} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 - - - -.. index:: RunningAvg - -.. _RunningAvg: - -RunningAvg ----------- - - - - - - -.. cfunction:: void cvRunningAvg( const CvArr* image, CvArr* acc, double alpha, const CvArr* mask=NULL ) - - Updates the running average. - - - - - - - :param image: Input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently) - - - :param acc: Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point - - - :param alpha: Weight of input image - - - :param mask: Optional operation mask - - - -The function calculates the weighted sum of the input image -``image`` -and the accumulator -``acc`` -so that -``acc`` -becomes a running average of frame sequence: - - - -.. math:: - - \texttt{acc} (x,y) \leftarrow (1- \alpha ) \cdot \texttt{acc} (x,y) + \alpha \cdot \texttt{image} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 - - -where -:math:`\alpha` -regulates the update speed (how fast the accumulator forgets about previous frames). - - -.. index:: SquareAcc - -.. _SquareAcc: - -SquareAcc ---------- - - - - - - -.. cfunction:: void cvSquareAcc( const CvArr* image, CvArr* sqsum, const CvArr* mask=NULL ) - - Adds the square of the source image to the accumulator. - - - - - - - :param image: Input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently) - - - :param sqsum: Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point - - - :param mask: Optional operation mask - - - -The function adds the input image -``image`` -or its selected region, raised to power 2, to the accumulator -``sqsum`` -: - - - -.. math:: - - \texttt{sqsum} (x,y) \leftarrow \texttt{sqsum} (x,y) + \texttt{image} (x,y)^2 \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 - - diff --git a/doc/opencv1/c/imgproc_object_detection.rst b/doc/opencv1/c/imgproc_object_detection.rst deleted file mode 100644 index e05f8542b1..0000000000 --- a/doc/opencv1/c/imgproc_object_detection.rst +++ /dev/null @@ -1,149 +0,0 @@ -Object Detection -================ - -.. highlight:: c - - - -.. index:: MatchTemplate - -.. _MatchTemplate: - -MatchTemplate -------------- - - - - - - -.. cfunction:: void cvMatchTemplate( const CvArr* image, const CvArr* templ, CvArr* result, int method ) - - Compares a template against overlapped image regions. - - - - - - - :param image: Image where the search is running; should be 8-bit or 32-bit floating-point - - - :param templ: Searched template; must be not greater than the source image and the same data type as the image - - - :param result: A map of comparison results; single-channel 32-bit floating-point. - If ``image`` is :math:`W \times H` and ``templ`` is :math:`w \times h` then ``result`` must be :math:`(W-w+1) \times (H-h+1)` - - - :param method: Specifies the way the template must be compared with the image regions (see below) - - - -The function is similar to -:ref:`CalcBackProjectPatch` -. It slides through -``image`` -, compares the -overlapped patches of size -:math:`w \times h` -against -``templ`` -using the specified method and stores the comparison results to -``result`` -. Here are the formulas for the different comparison -methods one may use ( -:math:`I` -denotes -``image`` -, -:math:`T` -``template`` -, -:math:`R` -``result`` -). The summation is done over template and/or the -image patch: -:math:`x' = 0...w-1, y' = 0...h-1` - - - - -* method=CV\_TM\_SQDIFF - - - .. math:: - - R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2 - - - - -* method=CV\_TM\_SQDIFF\_NORMED - - - .. math:: - - R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}} - - - - -* method=CV\_TM\_CCORR - - - .. math:: - - R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y')) - - - - -* method=CV\_TM\_CCORR\_NORMED - - - .. math:: - - R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}} - - - - -* method=CV\_TM\_CCOEFF - - - .. math:: - - R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) - - - where - - - .. math:: - - \begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array} - - - - -* method=CV\_TM\_CCOEFF\_NORMED - - - .. math:: - - R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} } - - - - -After the function finishes the comparison, the best matches can be found as global minimums ( -``CV_TM_SQDIFF`` -) or maximums ( -``CV_TM_CCORR`` -and -``CV_TM_CCOEFF`` -) using the -:ref:`MinMaxLoc` -function. In the case of a color image, template summation in the numerator and each sum in the denominator is done over all of the channels (and separate mean values are used for each channel). - diff --git a/doc/opencv1/c/imgproc_structural_analysis_and_shape_descriptors.rst b/doc/opencv1/c/imgproc_structural_analysis_and_shape_descriptors.rst deleted file mode 100644 index 830f026407..0000000000 --- a/doc/opencv1/c/imgproc_structural_analysis_and_shape_descriptors.rst +++ /dev/null @@ -1,1766 +0,0 @@ -Structural Analysis and Shape Descriptors -========================================= - -.. highlight:: c - - - -.. index:: ApproxChains - -.. _ApproxChains: - -ApproxChains ------------- - - - - - - -.. cfunction:: CvSeq* cvApproxChains( CvSeq* src_seq, CvMemStorage* storage, int method=CV_CHAIN_APPROX_SIMPLE, double parameter=0, int minimal_perimeter=0, int recursive=0 ) - - Approximates Freeman chain(s) with a polygonal curve. - - - - - - - :param src_seq: Pointer to the chain that can refer to other chains - - - :param storage: Storage location for the resulting polylines - - - :param method: Approximation method (see the description of the function :ref:`FindContours` ) - - - :param parameter: Method parameter (not used now) - - - :param minimal_perimeter: Approximates only those contours whose perimeters are not less than ``minimal_perimeter`` . Other chains are removed from the resulting structure - - - :param recursive: If not 0, the function approximates all chains that access can be obtained to from ``src_seq`` by using the ``h_next`` or ``v_next links`` . If 0, the single chain is approximated - - - -This is a stand-alone approximation routine. The function -``cvApproxChains`` -works exactly in the same way as -:ref:`FindContours` -with the corresponding approximation flag. The function returns pointer to the first resultant contour. Other approximated contours, if any, can be accessed via the -``v_next`` -or -``h_next`` -fields of the returned structure. - - -.. index:: ApproxPoly - -.. _ApproxPoly: - -ApproxPoly ----------- - - - - - - -.. cfunction:: CvSeq* cvApproxPoly( const void* src_seq, int header_size, CvMemStorage* storage, int method, double parameter, int parameter2=0 ) - - Approximates polygonal curve(s) with the specified precision. - - - - - - - :param src_seq: Sequence of an array of points - - - :param header_size: Header size of the approximated curve[s] - - - :param storage: Container for the approximated contours. If it is NULL, the input sequences' storage is used - - - :param method: Approximation method; only ``CV_POLY_APPROX_DP`` is supported, that corresponds to the Douglas-Peucker algorithm - - - :param parameter: Method-specific parameter; in the case of ``CV_POLY_APPROX_DP`` it is a desired approximation accuracy - - - :param parameter2: If case if ``src_seq`` is a sequence, the parameter determines whether the single sequence should be approximated or all sequences on the same level or below ``src_seq`` (see :ref:`FindContours` for description of hierarchical contour structures). If ``src_seq`` is an array CvMat* of points, the parameter specifies whether the curve is closed ( ``parameter2`` !=0) or not ( ``parameter2`` =0) - - - -The function approximates one or more curves and -returns the approximation result[s]. In the case of multiple curves, -the resultant tree will have the same structure as the input one (1:1 -correspondence). - - -.. index:: ArcLength - -.. _ArcLength: - -ArcLength ---------- - - - - - - -.. cfunction:: double cvArcLength( const void* curve, CvSlice slice=CV_WHOLE_SEQ, int isClosed=-1 ) - - Calculates the contour perimeter or the curve length. - - - - - - - :param curve: Sequence or array of the curve points - - - :param slice: Starting and ending points of the curve, by default, the whole curve length is calculated - - - :param isClosed: Indicates whether the curve is closed or not. There are 3 cases: - - - - * :math:`\texttt{isClosed}=0` the curve is assumed to be unclosed. - - - * :math:`\texttt{isClosed}>0` the curve is assumed to be closed. - - - * :math:`\texttt{isClosed}<0` if curve is sequence, the flag ``CV_SEQ_FLAG_CLOSED`` of ``((CvSeq*)curve)->flags`` is checked to determine if the curve is closed or not, otherwise (curve is represented by array (CvMat*) of points) it is assumed to be unclosed. - - - - -The function calculates the length or curve as the sum of lengths of segments between subsequent points - - -.. index:: BoundingRect - -.. _BoundingRect: - -BoundingRect ------------- - - - - - - -.. cfunction:: CvRect cvBoundingRect( CvArr* points, int update=0 ) - - Calculates the up-right bounding rectangle of a point set. - - - - - - - :param points: 2D point set, either a sequence or vector ( ``CvMat`` ) of points - - - :param update: The update flag. See below. - - - -The function returns the up-right bounding rectangle for a 2d point set. -Here is the list of possible combination of the flag values and type of -``points`` -: - - -.. table:: - - ====== ========================= ======================================================================================================= - update points action \ - ====== ========================= ======================================================================================================= - 0 ``CvContour*`` the bounding rectangle is not calculated, but it is taken from ``rect`` field of the contour header. \ - 1 ``CvContour*`` the bounding rectangle is calculated and written to ``rect`` field of the contour header. \ - 0 ``CvSeq*`` or ``CvMat*`` the bounding rectangle is calculated and returned. \ - 1 ``CvSeq*`` or ``CvMat*`` runtime error is raised. \ - ====== ========================= ======================================================================================================= - - -.. index:: BoxPoints - -.. _BoxPoints: - -BoxPoints ---------- - - - - - - -.. cfunction:: void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] ) - - Finds the box vertices. - - - - - - - :param box: Box - - - :param points: Array of vertices - - - -The function calculates the vertices of the input 2d box. - -Here is the function code: - - - - -:: - - - - void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] ) - { - float a = (float)cos(box.angle)*0.5f; - float b = (float)sin(box.angle)*0.5f; - - pt[0].x = box.center.x - a*box.size.height - b*box.size.width; - pt[0].y = box.center.y + b*box.size.height - a*box.size.width; - pt[1].x = box.center.x + a*box.size.height - b*box.size.width; - pt[1].y = box.center.y - b*box.size.height - a*box.size.width; - pt[2].x = 2*box.center.x - pt[0].x; - pt[2].y = 2*box.center.y - pt[0].y; - pt[3].x = 2*box.center.x - pt[1].x; - pt[3].y = 2*box.center.y - pt[1].y; - } - - -.. - - -.. index:: CalcPGH - -.. _CalcPGH: - -CalcPGH -------- - - - - - - -.. cfunction:: void cvCalcPGH( const CvSeq* contour, CvHistogram* hist ) - - Calculates a pair-wise geometrical histogram for a contour. - - - - - - - :param contour: Input contour. Currently, only integer point coordinates are allowed - - - :param hist: Calculated histogram; must be two-dimensional - - - -The function calculates a -2D pair-wise geometrical histogram (PGH), described in -:ref:`Iivarinen97` -for the contour. The algorithm considers every pair of contour -edges. The angle between the edges and the minimum/maximum distances -are determined for every pair. To do this each of the edges in turn -is taken as the base, while the function loops through all the other -edges. When the base edge and any other edge are considered, the minimum -and maximum distances from the points on the non-base edge and line of -the base edge are selected. The angle between the edges defines the row -of the histogram in which all the bins that correspond to the distance -between the calculated minimum and maximum distances are incremented -(that is, the histogram is transposed relatively to the -:ref:`Iivarninen97` -definition). The histogram can be used for contour matching. - - -.. index:: CalcEMD2 - -.. _CalcEMD2: - -CalcEMD2 --------- - - - - - - -.. cfunction:: float cvCalcEMD2( const CvArr* signature1, const CvArr* signature2, int distance_type, CvDistanceFunction distance_func=NULL, const CvArr* cost_matrix=NULL, CvArr* flow=NULL, float* lower_bound=NULL, void* userdata=NULL ) - - Computes the "minimal work" distance between two weighted point configurations. - - - - - - - :param signature1: First signature, a :math:`\texttt{size1}\times \texttt{dims}+1` floating-point matrix. Each row stores the point weight followed by the point coordinates. The matrix is allowed to have a single column (weights only) if the user-defined cost matrix is used - - - :param signature2: Second signature of the same format as ``signature1`` , though the number of rows may be different. The total weights may be different, in this case an extra "dummy" point is added to either ``signature1`` or ``signature2`` - - - :param distance_type: Metrics used; ``CV_DIST_L1, CV_DIST_L2`` , and ``CV_DIST_C`` stand for one of the standard metrics; ``CV_DIST_USER`` means that a user-defined function ``distance_func`` or pre-calculated ``cost_matrix`` is used - - - :param distance_func: The user-supplied distance function. It takes coordinates of two points and returns the distance between the points `` - typedef float (*CvDistanceFunction)(const float* f1, const float* f2, void* userdata);`` - - - :param cost_matrix: The user-defined :math:`\texttt{size1}\times \texttt{size2}` cost matrix. At least one of ``cost_matrix`` and ``distance_func`` must be NULL. Also, if a cost matrix is used, lower boundary (see below) can not be calculated, because it needs a metric function - - - :param flow: The resultant :math:`\texttt{size1} \times \texttt{size2}` flow matrix: :math:`\texttt{flow}_{i,j}` is a flow from :math:`i` th point of ``signature1`` to :math:`j` th point of ``signature2`` - - - :param lower_bound: Optional input/output parameter: lower boundary of distance between the two signatures that is a distance between mass centers. The lower boundary may not be calculated if the user-defined cost matrix is used, the total weights of point configurations are not equal, or if the signatures consist of weights only (i.e. the signature matrices have a single column). The user **must** initialize ``*lower_bound`` . If the calculated distance between mass centers is greater or equal to ``*lower_bound`` (it means that the signatures are far enough) the function does not calculate EMD. In any case ``*lower_bound`` is set to the calculated distance between mass centers on return. Thus, if user wants to calculate both distance between mass centers and EMD, ``*lower_bound`` should be set to 0 - - - :param userdata: Pointer to optional data that is passed into the user-defined distance function - - - -The function computes the earth mover distance and/or -a lower boundary of the distance between the two weighted point -configurations. One of the applications described in -:ref:`RubnerSept98` -is -multi-dimensional histogram comparison for image retrieval. EMD is a a -transportation problem that is solved using some modification of a simplex -algorithm, thus the complexity is exponential in the worst case, though, on average -it is much faster. In the case of a real metric the lower boundary -can be calculated even faster (using linear-time algorithm) and it can -be used to determine roughly whether the two signatures are far enough -so that they cannot relate to the same object. - - -.. index:: CheckContourConvexity - -.. _CheckContourConvexity: - -CheckContourConvexity ---------------------- - - - - - - -.. cfunction:: int cvCheckContourConvexity( const CvArr* contour ) - - Tests contour convexity. - - - - - - - :param contour: Tested contour (sequence or array of points) - - - -The function tests whether the input contour is convex or not. The contour must be simple, without self-intersections. - - -.. index:: CvConvexityDefect - -.. _CvConvexityDefect: - -CvConvexityDefect ------------------ - - - -.. ctype:: CvConvexityDefect - - - -Structure describing a single contour convexity defect. - - - - -:: - - - - typedef struct CvConvexityDefect - { - CvPoint* start; /* point of the contour where the defect begins */ - CvPoint* end; /* point of the contour where the defect ends */ - CvPoint* depth_point; /* the farthest from the convex hull point within the defect */ - float depth; /* distance between the farthest point and the convex hull */ - } CvConvexityDefect; - - -.. - - - -.. image:: ../pics/defects.png - - - - -.. index:: ContourArea - -.. _ContourArea: - -ContourArea ------------ - - - - - - -.. cfunction:: double cvContourArea( const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ ) - - Calculates the area of a whole contour or a contour section. - - - - - - - :param contour: Contour (sequence or array of vertices) - - - :param slice: Starting and ending points of the contour section of interest, by default, the area of the whole contour is calculated - - - -The function calculates the area of a whole contour -or a contour section. In the latter case the total area bounded by the -contour arc and the chord connecting the 2 selected points is calculated -as shown on the picture below: - - - -.. image:: ../pics/contoursecarea.png - - - -Orientation of the contour affects the area sign, thus the function may return a -*negative* -result. Use the -``fabs()`` -function from C runtime to get the absolute value of the area. - - -.. index:: ContourFromContourTree - -.. _ContourFromContourTree: - -ContourFromContourTree ----------------------- - - - - - - -.. cfunction:: CvSeq* cvContourFromContourTree( const CvContourTree* tree, CvMemStorage* storage, CvTermCriteria criteria ) - - Restores a contour from the tree. - - - - - - - :param tree: Contour tree - - - :param storage: Container for the reconstructed contour - - - :param criteria: Criteria, where to stop reconstruction - - - -The function restores the contour from its binary tree representation. The parameter -``criteria`` -determines the accuracy and/or the number of tree levels used for reconstruction, so it is possible to build an approximated contour. The function returns the reconstructed contour. - - -.. index:: ConvexHull2 - -.. _ConvexHull2: - -ConvexHull2 ------------ - - - - - - -.. cfunction:: CvSeq* cvConvexHull2( const CvArr* input, void* storage=NULL, int orientation=CV_CLOCKWISE, int return_points=0 ) - - Finds the convex hull of a point set. - - - - - - - :param points: Sequence or array of 2D points with 32-bit integer or floating-point coordinates - - - :param storage: The destination array (CvMat*) or memory storage (CvMemStorage*) that will store the convex hull. If it is an array, it should be 1d and have the same number of elements as the input array/sequence. On output the header is modified as to truncate the array down to the hull size. If ``storage`` is NULL then the convex hull will be stored in the same storage as the input sequence - - - :param orientation: Desired orientation of convex hull: ``CV_CLOCKWISE`` or ``CV_COUNTER_CLOCKWISE`` - - - :param return_points: If non-zero, the points themselves will be stored in the hull instead of indices if ``storage`` is an array, or pointers if ``storage`` is memory storage - - - -The function finds the convex hull of a 2D point set using Sklansky's algorithm. If -``storage`` -is memory storage, the function creates a sequence containing the hull points or pointers to them, depending on -``return_points`` -value and returns the sequence on output. If -``storage`` -is a CvMat, the function returns NULL. - -Example. Building convex hull for a sequence or array of points - - - - -:: - - - - #include "cv.h" - #include "highgui.h" - #include - - #define ARRAY 0 /* switch between array/sequence method by replacing 0<=>1 */ - - void main( int argc, char** argv ) - { - IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 ); - cvNamedWindow( "hull", 1 ); - - #if !ARRAY - CvMemStorage* storage = cvCreateMemStorage(); - #endif - - for(;;) - { - int i, count = rand() - CvPoint pt0; - #if !ARRAY - CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2, - sizeof(CvContour), - sizeof(CvPoint), - storage ); - CvSeq* hull; - - for( i = 0; i < count; i++ ) - { - pt0.x = rand() - pt0.y = rand() - cvSeqPush( ptseq, &pt0 ); - } - hull = cvConvexHull2( ptseq, 0, CV_CLOCKWISE, 0 ); - hullcount = hull->total; - #else - CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0])); - int* hull = (int*)malloc( count * sizeof(hull[0])); - CvMat point_mat = cvMat( 1, count, CV_32SC2, points ); - CvMat hull_mat = cvMat( 1, count, CV_32SC1, hull ); - - for( i = 0; i < count; i++ ) - { - pt0.x = rand() - pt0.y = rand() - points[i] = pt0; - } - cvConvexHull2( &point_mat, &hull_mat, CV_CLOCKWISE, 0 ); - hullcount = hull_mat.cols; - #endif - cvZero( img ); - for( i = 0; i < count; i++ ) - { - #if !ARRAY - pt0 = *CV_GET_SEQ_ELEM( CvPoint, ptseq, i ); - #else - pt0 = points[i]; - #endif - cvCircle( img, pt0, 2, CV_RGB( 255, 0, 0 ), CV_FILLED ); - } - - #if !ARRAY - pt0 = **CV_GET_SEQ_ELEM( CvPoint*, hull, hullcount - 1 ); - #else - pt0 = points[hull[hullcount-1]]; - #endif - - for( i = 0; i < hullcount; i++ ) - { - #if !ARRAY - CvPoint pt = **CV_GET_SEQ_ELEM( CvPoint*, hull, i ); - #else - CvPoint pt = points[hull[i]]; - #endif - cvLine( img, pt0, pt, CV_RGB( 0, 255, 0 )); - pt0 = pt; - } - - cvShowImage( "hull", img ); - - int key = cvWaitKey(0); - if( key == 27 ) // 'ESC' - break; - - #if !ARRAY - cvClearMemStorage( storage ); - #else - free( points ); - free( hull ); - #endif - } - } - - -.. - - -.. index:: ConvexityDefects - -.. _ConvexityDefects: - -ConvexityDefects ----------------- - - - - - - -.. cfunction:: CvSeq* cvConvexityDefects( const CvArr* contour, const CvArr* convexhull, CvMemStorage* storage=NULL ) - - Finds the convexity defects of a contour. - - - - - - - :param contour: Input contour - - - :param convexhull: Convex hull obtained using :ref:`ConvexHull2` that should contain pointers or indices to the contour points, not the hull points themselves (the ``return_points`` parameter in :ref:`ConvexHull2` should be 0) - - - :param storage: Container for the output sequence of convexity defects. If it is NULL, the contour or hull (in that order) storage is used - - - -The function finds all convexity defects of the input contour and returns a sequence of the CvConvexityDefect structures. - - -.. index:: CreateContourTree - -.. _CreateContourTree: - -CreateContourTree ------------------ - - - - - - -.. cfunction:: CvContourTree* cvCreateContourTree( const CvSeq* contour, CvMemStorage* storage, double threshold ) - - Creates a hierarchical representation of a contour. - - - - - - - :param contour: Input contour - - - :param storage: Container for output tree - - - :param threshold: Approximation accuracy - - - -The function creates a binary tree representation for the input -``contour`` -and returns the pointer to its root. If the parameter -``threshold`` -is less than or equal to 0, the function creates a full binary tree representation. If the threshold is greater than 0, the function creates a representation with the precision -``threshold`` -: if the vertices with the interceptive area of its base line are less than -``threshold`` -, the tree should not be built any further. The function returns the created tree. - - -.. index:: EndFindContours - -.. _EndFindContours: - -EndFindContours ---------------- - - - - - - -.. cfunction:: CvSeq* cvEndFindContours( CvContourScanner* scanner ) - - Finishes the scanning process. - - - - - - - :param scanner: Pointer to the contour scanner - - - -The function finishes the scanning process and returns a pointer to the first contour on the highest level. - - -.. index:: FindContours - -.. _FindContours: - -FindContours ------------- - - - - - - -.. cfunction:: int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_contour, int header_size=sizeof(CvContour), int mode=CV_RETR_LIST, int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) ) - - Finds the contours in a binary image. - - - - - - - :param image: The source, an 8-bit single channel image. Non-zero pixels are treated as 1's, zero pixels remain 0's - the image is treated as ``binary`` . To get such a binary image from grayscale, one may use :ref:`Threshold` , :ref:`AdaptiveThreshold` or :ref:`Canny` . The function modifies the source image's content - - - :param storage: Container of the retrieved contours - - - :param first_contour: Output parameter, will contain the pointer to the first outer contour - - - :param header_size: Size of the sequence header, :math:`\ge \texttt{sizeof(CvChain)}` if :math:`\texttt{method} =\texttt{CV\_CHAIN\_CODE}` , - and :math:`\ge \texttt{sizeof(CvContour)}` otherwise - - - :param mode: Retrieval mode - - - * **CV_RETR_EXTERNAL** retrives only the extreme outer contours - - - * **CV_RETR_LIST** retrieves all of the contours and puts them in the list - - - * **CV_RETR_CCOMP** retrieves all of the contours and organizes them into a two-level hierarchy: on the top level are the external boundaries of the components, on the second level are the boundaries of the holes - - - * **CV_RETR_TREE** retrieves all of the contours and reconstructs the full hierarchy of nested contours - - - - - :param method: Approximation method (for all the modes, except ``CV_LINK_RUNS`` , which uses built-in approximation) - - - * **CV_CHAIN_CODE** outputs contours in the Freeman chain code. All other methods output polygons (sequences of vertices) - - - * **CV_CHAIN_APPROX_NONE** translates all of the points from the chain code into points - - - * **CV_CHAIN_APPROX_SIMPLE** compresses horizontal, vertical, and diagonal segments and leaves only their end points - - - * **CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS** applies one of the flavors of the Teh-Chin chain approximation algorithm. - - - * **CV_LINK_RUNS** uses a completely different contour retrieval algorithm by linking horizontal segments of 1's. Only the ``CV_RETR_LIST`` retrieval mode can be used with this method. - - - - - :param offset: Offset, by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context - - - -The function retrieves contours from the binary image using the algorithm -Suzuki85 -. The contours are a useful tool for shape analysis and -object detection and recognition. - -The function retrieves contours from the -binary image and returns the number of retrieved contours. The -pointer -``first_contour`` -is filled by the function. It will -contain a pointer to the first outermost contour or -``NULL`` -if no -contours are detected (if the image is completely black). Other -contours may be reached from -``first_contour`` -using the -``h_next`` -and -``v_next`` -links. The sample in the -:ref:`DrawContours` -discussion shows how to use contours for -connected component detection. Contours can be also used for shape -analysis and object recognition - see -``squares.c`` -in the OpenCV sample directory. - -**Note:** -the source -``image`` -is modified by this function. - - -.. index:: FindNextContour - -.. _FindNextContour: - -FindNextContour ---------------- - - - - - - -.. cfunction:: CvSeq* cvFindNextContour( CvContourScanner scanner ) - - Finds the next contour in the image. - - - - - - - :param scanner: Contour scanner initialized by :ref:`StartFindContours` - - - -The function locates and retrieves the next contour in the image and returns a pointer to it. The function returns NULL if there are no more contours. - - -.. index:: FitEllipse2 - -.. _FitEllipse2: - -FitEllipse2 ------------ - - - - - - -.. cfunction:: CvBox2D cvFitEllipse2( const CvArr* points ) - - Fits an ellipse around a set of 2D points. - - - - - - - :param points: Sequence or array of points - - - -The function calculates the ellipse that fits best -(in least-squares sense) around a set of 2D points. The meaning of the -returned structure fields is similar to those in -:ref:`Ellipse` -except -that -``size`` -stores the full lengths of the ellipse axises, -not half-lengths. - - -.. index:: FitLine - -.. _FitLine: - -FitLine -------- - - - - - - -.. cfunction:: void cvFitLine( const CvArr* points, int dist_type, double param, double reps, double aeps, float* line ) - - Fits a line to a 2D or 3D point set. - - - - - - - :param points: Sequence or array of 2D or 3D points with 32-bit integer or floating-point coordinates - - - :param dist_type: The distance used for fitting (see the discussion) - - - :param param: Numerical parameter ( ``C`` ) for some types of distances, if 0 then some optimal value is chosen - - - :param reps: Sufficient accuracy for the radius (distance between the coordinate origin and the line). 0.01 is a good default value. - - - :param aeps: Sufficient accuracy for the angle. 0.01 is a good default value. - - - :param line: The output line parameters. In the case of a 2d fitting, - it is an array of 4 floats ``(vx, vy, x0, y0)`` where ``(vx, vy)`` is a normalized vector collinear to the - line and ``(x0, y0)`` is some point on the line. in the case of a - 3D fitting it is an array of 6 floats ``(vx, vy, vz, x0, y0, z0)`` - where ``(vx, vy, vz)`` is a normalized vector collinear to the line - and ``(x0, y0, z0)`` is some point on the line - - - -The function fits a line to a 2D or 3D point set by minimizing -:math:`\sum_i \rho(r_i)` -where -:math:`r_i` -is the distance between the -:math:`i` -th point and the line and -:math:`\rho(r)` -is a distance function, one of: - - - - - -* dist\_type=CV\_DIST\_L2 - - - .. math:: - - \rho (r) = r^2/2 \quad \text{(the simplest and the fastest least-squares method)} - - - - -* dist\_type=CV\_DIST\_L1 - - - .. math:: - - \rho (r) = r - - - - -* dist\_type=CV\_DIST\_L12 - - - .. math:: - - \rho (r) = 2 \cdot ( \sqrt{1 + \frac{r^2}{2}} - 1) - - - - -* dist\_type=CV\_DIST\_FAIR - - - .. math:: - - \rho \left (r \right ) = C^2 \cdot \left ( \frac{r}{C} - \log{\left(1 + \frac{r}{C}\right)} \right ) \quad \text{where} \quad C=1.3998 - - - - -* dist\_type=CV\_DIST\_WELSCH - - - .. math:: - - \rho \left (r \right ) = \frac{C^2}{2} \cdot \left ( 1 - \exp{\left(-\left(\frac{r}{C}\right)^2\right)} \right ) \quad \text{where} \quad C=2.9846 - - - - -* dist\_type=CV\_DIST\_HUBER - - - .. math:: - - \rho (r) = \fork{r^2/2}{if $r < C$}{C \cdot (r-C/2)}{otherwise} \quad \text{where} \quad C=1.345 - - - - - -.. index:: GetCentralMoment - -.. _GetCentralMoment: - -GetCentralMoment ----------------- - - - - - - -.. cfunction:: double cvGetCentralMoment( CvMoments* moments, int x_order, int y_order ) - - Retrieves the central moment from the moment state structure. - - - - - - - :param moments: Pointer to the moment state structure - - - :param x_order: x order of the retrieved moment, :math:`\texttt{x\_order} >= 0` - - - :param y_order: y order of the retrieved moment, :math:`\texttt{y\_order} >= 0` and :math:`\texttt{x\_order} + \texttt{y\_order} <= 3` - - - -The function retrieves the central moment, which in the case of image moments is defined as: - - - -.. math:: - - \mu _{x \_ order, \, y \_ order} = \sum _{x,y} (I(x,y) \cdot (x-x_c)^{x \_ order} \cdot (y-y_c)^{y \_ order}) - - -where -:math:`x_c,y_c` -are the coordinates of the gravity center: - - - -.. math:: - - x_c= \frac{M_{10}}{M_{00}} , y_c= \frac{M_{01}}{M_{00}} - - - -.. index:: GetHuMoments - -.. _GetHuMoments: - -GetHuMoments ------------- - - - - - - -.. cfunction:: void cvGetHuMoments( const CvMoments* moments,CvHuMoments* hu ) - - Calculates the seven Hu invariants. - - - - - - - :param moments: The input moments, computed with :ref:`Moments` - - - :param hu: The output Hu invariants - - - -The function calculates the seven Hu invariants, see -http://en.wikipedia.org/wiki/Image_moment -, that are defined as: - - - -.. math:: - - \begin{array}{l} hu_1= \eta _{20}+ \eta _{02} \\ hu_2=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu_3=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu_4=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu_5=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu_6=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu_7=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array} - - -where -:math:`\eta_{ji}` -denote the normalized central moments. - -These values are proved to be invariant to the image scale, rotation, and reflection except the seventh one, whose sign is changed by reflection. Of course, this invariance was proved with the assumption of infinite image resolution. In case of a raster images the computed Hu invariants for the original and transformed images will be a bit different. - - -.. index:: GetNormalizedCentralMoment - -.. _GetNormalizedCentralMoment: - -GetNormalizedCentralMoment --------------------------- - - - - - - -.. cfunction:: double cvGetNormalizedCentralMoment( CvMoments* moments, int x_order, int y_order ) - - Retrieves the normalized central moment from the moment state structure. - - - - - - - :param moments: Pointer to the moment state structure - - - :param x_order: x order of the retrieved moment, :math:`\texttt{x\_order} >= 0` - - - :param y_order: y order of the retrieved moment, :math:`\texttt{y\_order} >= 0` and :math:`\texttt{x\_order} + \texttt{y\_order} <= 3` - - - -The function retrieves the normalized central moment: - - - -.. math:: - - \eta _{x \_ order, \, y \_ order} = \frac{\mu_{x\_order, \, y\_order}}{M_{00}^{(y\_order+x\_order)/2+1}} - - - -.. index:: GetSpatialMoment - -.. _GetSpatialMoment: - -GetSpatialMoment ----------------- - - - - - - -.. cfunction:: double cvGetSpatialMoment( CvMoments* moments, int x_order, int y_order ) - - Retrieves the spatial moment from the moment state structure. - - - - - - - :param moments: The moment state, calculated by :ref:`Moments` - - - :param x_order: x order of the retrieved moment, :math:`\texttt{x\_order} >= 0` - - - :param y_order: y order of the retrieved moment, :math:`\texttt{y\_order} >= 0` and :math:`\texttt{x\_order} + \texttt{y\_order} <= 3` - - - -The function retrieves the spatial moment, which in the case of image moments is defined as: - - - -.. math:: - - M_{x \_ order, \, y \_ order} = \sum _{x,y} (I(x,y) \cdot x^{x \_ order} \cdot y^{y \_ order}) - - -where -:math:`I(x,y)` -is the intensity of the pixel -:math:`(x, y)` -. - - -.. index:: MatchContourTrees - -.. _MatchContourTrees: - -MatchContourTrees ------------------ - - - - - - -.. cfunction:: double cvMatchContourTrees( const CvContourTree* tree1, const CvContourTree* tree2, int method, double threshold ) - - Compares two contours using their tree representations. - - - - - - - :param tree1: First contour tree - - - :param tree2: Second contour tree - - - :param method: Similarity measure, only ``CV_CONTOUR_TREES_MATCH_I1`` is supported - - - :param threshold: Similarity threshold - - - -The function calculates the value of the matching measure for two contour trees. The similarity measure is calculated level by level from the binary tree roots. If at a certain level the difference between contours becomes less than -``threshold`` -, the reconstruction process is interrupted and the current difference is returned. - - -.. index:: MatchShapes - -.. _MatchShapes: - -MatchShapes ------------ - - - - - - -.. cfunction:: double cvMatchShapes( const void* object1, const void* object2, int method, double parameter=0 ) - - Compares two shapes. - - - - - - - :param object1: First contour or grayscale image - - - :param object2: Second contour or grayscale image - - - :param method: Comparison method; - ``CV_CONTOURS_MATCH_I1`` , - ``CV_CONTOURS_MATCH_I2`` - or - ``CV_CONTOURS_MATCH_I3`` - - - :param parameter: Method-specific parameter (is not used now) - - - -The function compares two shapes. The 3 implemented methods all use Hu moments (see -:ref:`GetHuMoments` -) ( -:math:`A` -is -``object1`` -, -:math:`B` -is -``object2`` -): - - - - - -* method=CV\_CONTOURS\_MATCH\_I1 - - - .. math:: - - I_1(A,B) = \sum _{i=1...7} \left | \frac{1}{m^A_i} - \frac{1}{m^B_i} \right | - - - - -* method=CV\_CONTOURS\_MATCH\_I2 - - - .. math:: - - I_2(A,B) = \sum _{i=1...7} \left | m^A_i - m^B_i \right | - - - - -* method=CV\_CONTOURS\_MATCH\_I3 - - - .. math:: - - I_3(A,B) = \sum _{i=1...7} \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| } - - - - -where - - - -.. math:: - - \begin{array}{l} m^A_i = sign(h^A_i) \cdot \log{h^A_i} m^B_i = sign(h^B_i) \cdot \log{h^B_i} \end{array} - - -and -:math:`h^A_i, h^B_i` -are the Hu moments of -:math:`A` -and -:math:`B` -respectively. - - - -.. index:: MinAreaRect2 - -.. _MinAreaRect2: - -MinAreaRect2 ------------- - - - - - - -.. cfunction:: CvBox2D cvMinAreaRect2( const CvArr* points, CvMemStorage* storage=NULL ) - - Finds the circumscribed rectangle of minimal area for a given 2D point set. - - - - - - - :param points: Sequence or array of points - - - :param storage: Optional temporary memory storage - - - -The function finds a circumscribed rectangle of the minimal area for a 2D point set by building a convex hull for the set and applying the rotating calipers technique to the hull. - -Picture. Minimal-area bounding rectangle for contour - - - -.. image:: ../pics/minareabox.png - - - - -.. index:: MinEnclosingCircle - -.. _MinEnclosingCircle: - -MinEnclosingCircle ------------------- - - - - - - -.. cfunction:: int cvMinEnclosingCircle( const CvArr* points, CvPoint2D32f* center, float* radius ) - - Finds the circumscribed circle of minimal area for a given 2D point set. - - - - - - - :param points: Sequence or array of 2D points - - - :param center: Output parameter; the center of the enclosing circle - - - :param radius: Output parameter; the radius of the enclosing circle - - - -The function finds the minimal circumscribed -circle for a 2D point set using an iterative algorithm. It returns nonzero -if the resultant circle contains all the input points and zero otherwise -(i.e. the algorithm failed). - - -.. index:: Moments - -.. _Moments: - -Moments -------- - - - - - - -.. cfunction:: void cvMoments( const CvArr* arr, CvMoments* moments, int binary=0 ) - - Calculates all of the moments up to the third order of a polygon or rasterized shape. - - - - - - - :param arr: Image (1-channel or 3-channel with COI set) or polygon (CvSeq of points or a vector of points) - - - :param moments: Pointer to returned moment's state structure - - - :param binary: (For images only) If the flag is non-zero, all of the zero pixel values are treated as zeroes, and all of the others are treated as 1's - - - -The function calculates spatial and central moments up to the third order and writes them to -``moments`` -. The moments may then be used then to calculate the gravity center of the shape, its area, main axises and various shape characeteristics including 7 Hu invariants. - - -.. index:: PointPolygonTest - -.. _PointPolygonTest: - -PointPolygonTest ----------------- - - - - - - -.. cfunction:: double cvPointPolygonTest( const CvArr* contour, CvPoint2D32f pt, int measure_dist ) - - Point in contour test. - - - - - - - :param contour: Input contour - - - :param pt: The point tested against the contour - - - :param measure_dist: If it is non-zero, the function estimates the distance from the point to the nearest contour edge - - - -The function determines whether the -point is inside a contour, outside, or lies on an edge (or coinsides -with a vertex). It returns positive, negative or zero value, -correspondingly. When -:math:`\texttt{measure\_dist} =0` -, the return value -is +1, -1 and 0, respectively. When -:math:`\texttt{measure\_dist} \ne 0` -, -it is a signed distance between the point and the nearest contour -edge. - -Here is the sample output of the function, where each image pixel is tested against the contour. - - - -.. image:: ../pics/pointpolygon.png - - - - -.. index:: PointSeqFromMat - -.. _PointSeqFromMat: - -PointSeqFromMat ---------------- - - - - - - -.. cfunction:: CvSeq* cvPointSeqFromMat( int seq_kind, const CvArr* mat, CvContour* contour_header, CvSeqBlock* block ) - - Initializes a point sequence header from a point vector. - - - - - - - :param seq_kind: Type of the point sequence: point set (0), a curve ( ``CV_SEQ_KIND_CURVE`` ), closed curve ( ``CV_SEQ_KIND_CURVE+CV_SEQ_FLAG_CLOSED`` ) etc. - - - :param mat: Input matrix. It should be a continuous, 1-dimensional vector of points, that is, it should have type ``CV_32SC2`` or ``CV_32FC2`` - - - :param contour_header: Contour header, initialized by the function - - - :param block: Sequence block header, initialized by the function - - - -The function initializes a sequence -header to create a "virtual" sequence in which elements reside in -the specified matrix. No data is copied. The initialized sequence -header may be passed to any function that takes a point sequence -on input. No extra elements can be added to the sequence, -but some may be removed. The function is a specialized variant of -:ref:`MakeSeqHeaderForArray` -and uses -the latter internally. It returns a pointer to the initialized contour -header. Note that the bounding rectangle (field -``rect`` -of -``CvContour`` -strucuture) is not initialized by the function. If -you need one, use -:ref:`BoundingRect` -. - -Here is a simple usage example. - - - - -:: - - - - CvContour header; - CvSeqBlock block; - CvMat* vector = cvCreateMat( 1, 3, CV_32SC2 ); - - CV_MAT_ELEM( *vector, CvPoint, 0, 0 ) = cvPoint(100,100); - CV_MAT_ELEM( *vector, CvPoint, 0, 1 ) = cvPoint(100,200); - CV_MAT_ELEM( *vector, CvPoint, 0, 2 ) = cvPoint(200,100); - - IplImage* img = cvCreateImage( cvSize(300,300), 8, 3 ); - cvZero(img); - - cvDrawContours( img, - cvPointSeqFromMat(CV_SEQ_KIND_CURVE+CV_SEQ_FLAG_CLOSED, - vector, - &header, - &block), - CV_RGB(255,0,0), - CV_RGB(255,0,0), - 0, 3, 8, cvPoint(0,0)); - - -.. - - -.. index:: ReadChainPoint - -.. _ReadChainPoint: - -ReadChainPoint --------------- - - - - - - -.. cfunction:: CvPoint cvReadChainPoint( CvChainPtReader* reader ) - - Gets the next chain point. - - - - - - - :param reader: Chain reader state - - - -The function returns the current chain point and updates the reader position. - - -.. index:: StartFindContours - -.. _StartFindContours: - -StartFindContours ------------------ - - - - - - -.. cfunction:: CvContourScanner cvStartFindContours( CvArr* image, CvMemStorage* storage, int header_size=sizeof(CvContour), int mode=CV_RETR_LIST, int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0,0) ) - - Initializes the contour scanning process. - - - - - - - :param image: The 8-bit, single channel, binary source image - - - :param storage: Container of the retrieved contours - - - :param header_size: Size of the sequence header, :math:`>=sizeof(CvChain)` if ``method`` =CV _ CHAIN _ CODE, and :math:`>=sizeof(CvContour)` otherwise - - - :param mode: Retrieval mode; see :ref:`FindContours` - - - :param method: Approximation method. It has the same meaning in :ref:`FindContours` , but ``CV_LINK_RUNS`` can not be used here - - - :param offset: ROI offset; see :ref:`FindContours` - - - -The function initializes and returns a pointer to the contour scanner. The scanner is used in -:ref:`FindNextContour` -to retrieve the rest of the contours. - - -.. index:: StartReadChainPoints - -.. _StartReadChainPoints: - -StartReadChainPoints --------------------- - - - - - - -.. cfunction:: void cvStartReadChainPoints( CvChain* chain, CvChainPtReader* reader ) - - Initializes the chain reader. - - - -The function initializes a special reader. - - -.. index:: SubstituteContour - -.. _SubstituteContour: - -SubstituteContour ------------------ - - - - - - -.. cfunction:: void cvSubstituteContour( CvContourScanner scanner, CvSeq* new_contour ) - - Replaces a retrieved contour. - - - - - - - :param scanner: Contour scanner initialized by :ref:`StartFindContours` - - - :param new_contour: Substituting contour - - - -The function replaces the retrieved -contour, that was returned from the preceding call of -:ref:`FindNextContour` -and stored inside the contour scanner -state, with the user-specified contour. The contour is inserted -into the resulting structure, list, two-level hierarchy, or tree, -depending on the retrieval mode. If the parameter -``new_contour`` -is -``NULL`` -, the retrieved contour is not included in the -resulting structure, nor are any of its children that might be added -to this structure later. - diff --git a/doc/opencv1/c/objdetect.rst b/doc/opencv1/c/objdetect.rst deleted file mode 100644 index 4c2b983f15..0000000000 --- a/doc/opencv1/c/objdetect.rst +++ /dev/null @@ -1,10 +0,0 @@ -*************************** -objdetect. Object Detection -*************************** - - - -.. toctree:: - :maxdepth: 2 - - objdetect_cascade_classification diff --git a/doc/opencv1/c/objdetect_cascade_classification.rst b/doc/opencv1/c/objdetect_cascade_classification.rst deleted file mode 100644 index 1f4b497f26..0000000000 --- a/doc/opencv1/c/objdetect_cascade_classification.rst +++ /dev/null @@ -1,521 +0,0 @@ -Cascade Classification -====================== - -.. highlight:: c - - - -Haar Feature-based Cascade Classifier for Object Detection ----------------------------------------------------------- - - -The object detector described below has been initially proposed by Paul Viola -:ref:`Viola01` -and improved by Rainer Lienhart -:ref:`Lienhart02` -. First, a classifier (namely a -*cascade of boosted classifiers working with haar-like features* -) is trained with a few hundred sample views of a particular object (i.e., a face or a car), called positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary images of the same size. - -After a classifier is trained, it can be applied to a region of interest -(of the same size as used during the training) in an input image. The -classifier outputs a "1" if the region is likely to show the object -(i.e., face/car), and "0" otherwise. To search for the object in the -whole image one can move the search window across the image and check -every location using the classifier. The classifier is designed so that -it can be easily "resized" in order to be able to find the objects of -interest at different sizes, which is more efficient than resizing the -image itself. So, to find an object of an unknown size in the image the -scan procedure should be done several times at different scales. - -The word "cascade" in the classifier name means that the resultant -classifier consists of several simpler classifiers ( -*stages* -) that -are applied subsequently to a region of interest until at some stage the -candidate is rejected or all the stages are passed. The word "boosted" -means that the classifiers at every stage of the cascade are complex -themselves and they are built out of basic classifiers using one of four -different -``boosting`` -techniques (weighted voting). Currently -Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are -supported. The basic classifiers are decision-tree classifiers with at -least 2 leaves. Haar-like features are the input to the basic classifers, -and are calculated as described below. The current algorithm uses the -following Haar-like features: - - - -.. image:: ../pics/haarfeatures.png - - - -The feature used in a particular classifier is specified by its shape (1a, 2b etc.), position within the region of interest and the scale (this scale is not the same as the scale used at the detection stage, though these two scales are multiplied). For example, in the case of the third line feature (2c) the response is calculated as the difference between the sum of image pixels under the rectangle covering the whole feature (including the two white stripes and the black stripe in the middle) and the sum of the image pixels under the black stripe multiplied by 3 in order to compensate for the differences in the size of areas. The sums of pixel values over a rectangular regions are calculated rapidly using integral images (see below and the -:ref:`Integral` -description). - -To see the object detector at work, have a look at the HaarFaceDetect demo. - -The following reference is for the detection part only. There -is a separate application called -``haartraining`` -that can -train a cascade of boosted classifiers from a set of samples. See -``opencv/apps/haartraining`` -for details. - - -.. index:: CvHaarFeature, CvHaarClassifier, CvHaarStageClassifier, CvHaarClassifierCascade - -.. _CvHaarFeature, CvHaarClassifier, CvHaarStageClassifier, CvHaarClassifierCascade: - -CvHaarFeature, CvHaarClassifier, CvHaarStageClassifier, CvHaarClassifierCascade -------------------------------------------------------------------------------- - - - -.. ctype:: CvHaarFeature, CvHaarClassifier, CvHaarStageClassifier, CvHaarClassifierCascade - - - -Boosted Haar classifier structures. - - - - -:: - - - - #define CV_HAAR_FEATURE_MAX 3 - - /* a haar feature consists of 2-3 rectangles with appropriate weights */ - typedef struct CvHaarFeature - { - int tilted; /* 0 means up-right feature, 1 means 45--rotated feature */ - - /* 2-3 rectangles with weights of opposite signs and - with absolute values inversely proportional to the areas of the - rectangles. If rect[2].weight !=0, then - the feature consists of 3 rectangles, otherwise it consists of 2 */ - struct - { - CvRect r; - float weight; - } rect[CV_HAAR_FEATURE_MAX]; - } - CvHaarFeature; - - /* a single tree classifier (stump in the simplest case) that returns the - response for the feature at the particular image location (i.e. pixel - sum over subrectangles of the window) and gives out a value depending - on the response */ - typedef struct CvHaarClassifier - { - int count; /* number of nodes in the decision tree */ - - /* these are "parallel" arrays. Every index ``i`` - corresponds to a node of the decision tree (root has 0-th index). - - left[i] - index of the left child (or negated index if the - left child is a leaf) - right[i] - index of the right child (or negated index if the - right child is a leaf) - threshold[i] - branch threshold. if feature responce is <= threshold, - left branch is chosen, otherwise right branch is chosen. - alpha[i] - output value correponding to the leaf. */ - CvHaarFeature* haar_feature; - float* threshold; - int* left; - int* right; - float* alpha; - } - CvHaarClassifier; - - /* a boosted battery of classifiers(=stage classifier): - the stage classifier returns 1 - if the sum of the classifiers responses - is greater than ``threshold`` and 0 otherwise */ - typedef struct CvHaarStageClassifier - { - int count; /* number of classifiers in the battery */ - float threshold; /* threshold for the boosted classifier */ - CvHaarClassifier* classifier; /* array of classifiers */ - - /* these fields are used for organizing trees of stage classifiers, - rather than just stright cascades */ - int next; - int child; - int parent; - } - CvHaarStageClassifier; - - typedef struct CvHidHaarClassifierCascade CvHidHaarClassifierCascade; - - /* cascade or tree of stage classifiers */ - typedef struct CvHaarClassifierCascade - { - int flags; /* signature */ - int count; /* number of stages */ - CvSize orig_window_size; /* original object size (the cascade is - trained for) */ - - /* these two parameters are set by cvSetImagesForHaarClassifierCascade */ - CvSize real_window_size; /* current object size */ - double scale; /* current scale */ - CvHaarStageClassifier* stage_classifier; /* array of stage classifiers */ - CvHidHaarClassifierCascade* hid_cascade; /* hidden optimized - representation of the - cascade, created by - cvSetImagesForHaarClassifierCascade */ - } - CvHaarClassifierCascade; - - -.. - -All the structures are used for representing a cascaded of boosted Haar classifiers. The cascade has the following hierarchical structure: - -:: - - Cascade: - Stage,,1,,: - Classifier,,11,,: - Feature,,11,, - Classifier,,12,,: - Feature,,12,, - ... - Stage,,2,,: - Classifier,,21,,: - Feature,,21,, - ... - ... - -The whole hierarchy can be constructed manually or loaded from a file or an embedded base using the function -:ref:`LoadHaarClassifierCascade` -. - - -.. index:: LoadHaarClassifierCascade - -.. _LoadHaarClassifierCascade: - -LoadHaarClassifierCascade -------------------------- - - - - - - -.. cfunction:: CvHaarClassifierCascade* cvLoadHaarClassifierCascade( const char* directory, CvSize orig_window_size ) - - Loads a trained cascade classifier from a file or the classifier database embedded in OpenCV. - - - - - - - :param directory: Name of the directory containing the description of a trained cascade classifier - - - :param orig_window_size: Original size of the objects the cascade has been trained on. Note that it is not stored in the cascade and therefore must be specified separately - - - -The function loads a trained cascade -of haar classifiers from a file or the classifier database embedded in -OpenCV. The base can be trained using the -``haartraining`` -application -(see opencv/apps/haartraining for details). - -**The function is obsolete** -. Nowadays object detection classifiers are stored in XML or YAML files, rather than in directories. To load a cascade from a file, use the -:ref:`Load` -function. - - -.. index:: HaarDetectObjects - -.. _HaarDetectObjects: - -HaarDetectObjects ------------------ - - - - - - - -:: - - - - - -.. - - - -.. cfunction:: CvSeq* cvHaarDetectObjects( const CvArr* image, CvHaarClassifierCascade* cascade, CvMemStorage* storage, double scaleFactor=1.1, int minNeighbors=3, int flags=0, CvSize minSize=cvSize(0, 0), CvSize maxSize=cvSize(0,0) ) - - Detects objects in the image. - -typedef struct CvAvgComp -{ - CvRect rect; /* bounding rectangle for the object (average rectangle of a group) */ - int neighbors; /* number of neighbor rectangles in the group */ -} -CvAvgComp; - - - - - - :param image: Image to detect objects in - - - :param cascade: Haar classifier cascade in internal representation - - - :param storage: Memory storage to store the resultant sequence of the object candidate rectangles - - - :param scaleFactor: The factor by which the search window is scaled between the subsequent scans, 1.1 means increasing window by 10 % - - - :param minNeighbors: Minimum number (minus 1) of neighbor rectangles that makes up an object. All the groups of a smaller number of rectangles than ``min_neighbors`` -1 are rejected. If ``minNeighbors`` is 0, the function does not any grouping at all and returns all the detected candidate rectangles, which may be useful if the user wants to apply a customized grouping procedure - - - :param flags: Mode of operation. Currently the only flag that may be specified is ``CV_HAAR_DO_CANNY_PRUNING`` . If it is set, the function uses Canny edge detector to reject some image regions that contain too few or too much edges and thus can not contain the searched object. The particular threshold values are tuned for face detection and in this case the pruning speeds up the processing - - - :param minSize: Minimum window size. By default, it is set to the size of samples the classifier has been trained on ( :math:`\sim 20\times 20` for face detection) - - - :param maxSize: Maximum window size to use. By default, it is set to the size of the image. - - - -The function finds rectangular regions in the given image that are likely to contain objects the cascade has been trained for and returns those regions as a sequence of rectangles. The function scans the image several times at different scales (see -:ref:`SetImagesForHaarClassifierCascade` -). Each time it considers overlapping regions in the image and applies the classifiers to the regions using -:ref:`RunHaarClassifierCascade` -. It may also apply some heuristics to reduce number of analyzed regions, such as Canny prunning. After it has proceeded and collected the candidate rectangles (regions that passed the classifier cascade), it groups them and returns a sequence of average rectangles for each large enough group. The default parameters ( -``scale_factor`` -=1.1, -``min_neighbors`` -=3, -``flags`` -=0) are tuned for accurate yet slow object detection. For a faster operation on real video images the settings are: -``scale_factor`` -=1.2, -``min_neighbors`` -=2, -``flags`` -= -``CV_HAAR_DO_CANNY_PRUNING`` -, -``min_size`` -= -*minimum possible face size* -(for example, -:math:`\sim` -1/4 to 1/16 of the image area in the case of video conferencing). - - - - -:: - - - - #include "cv.h" - #include "highgui.h" - - CvHaarClassifierCascade* load_object_detector( const char* cascade_path ) - { - return (CvHaarClassifierCascade*)cvLoad( cascade_path ); - } - - void detect_and_draw_objects( IplImage* image, - CvHaarClassifierCascade* cascade, - int do_pyramids ) - { - IplImage* small_image = image; - CvMemStorage* storage = cvCreateMemStorage(0); - CvSeq* faces; - int i, scale = 1; - - /* if the flag is specified, down-scale the input image to get a - performance boost w/o loosing quality (perhaps) */ - if( do_pyramids ) - { - small_image = cvCreateImage( cvSize(image->width/2,image->height/2), IPL_DEPTH_8U, 3 ); - cvPyrDown( image, small_image, CV_GAUSSIAN_5x5 ); - scale = 2; - } - - /* use the fastest variant */ - faces = cvHaarDetectObjects( small_image, cascade, storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING ); - - /* draw all the rectangles */ - for( i = 0; i < faces->total; i++ ) - { - /* extract the rectanlges only */ - CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i ); - cvRectangle( image, cvPoint(face_rect.x*scale,face_rect.y*scale), - cvPoint((face_rect.x+face_rect.width)*scale, - (face_rect.y+face_rect.height)*scale), - CV_RGB(255,0,0), 3 ); - } - - if( small_image != image ) - cvReleaseImage( &small_image ); - cvReleaseMemStorage( &storage ); - } - - /* takes image filename and cascade path from the command line */ - int main( int argc, char** argv ) - { - IplImage* image; - if( argc==3 && (image = cvLoadImage( argv[1], 1 )) != 0 ) - { - CvHaarClassifierCascade* cascade = load_object_detector(argv[2]); - detect_and_draw_objects( image, cascade, 1 ); - cvNamedWindow( "test", 0 ); - cvShowImage( "test", image ); - cvWaitKey(0); - cvReleaseHaarClassifierCascade( &cascade ); - cvReleaseImage( &image ); - } - - return 0; - } - - -.. - - -.. index:: SetImagesForHaarClassifierCascade - -.. _SetImagesForHaarClassifierCascade: - -SetImagesForHaarClassifierCascade ---------------------------------- - - - - - - -.. cfunction:: void cvSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* cascade, const CvArr* sum, const CvArr* sqsum, const CvArr* tilted_sum, double scale ) - - Assigns images to the hidden cascade. - - - - - - - :param cascade: Hidden Haar classifier cascade, created by :ref:`CreateHidHaarClassifierCascade` - - - :param sum: Integral (sum) single-channel image of 32-bit integer format. This image as well as the two subsequent images are used for fast feature evaluation and brightness/contrast normalization. They all can be retrieved from input 8-bit or floating point single-channel image using the function :ref:`Integral` - - - :param sqsum: Square sum single-channel image of 64-bit floating-point format - - - :param tilted_sum: Tilted sum single-channel image of 32-bit integer format - - - :param scale: Window scale for the cascade. If ``scale`` =1, the original window size is used (objects of that size are searched) - the same size as specified in :ref:`LoadHaarClassifierCascade` (24x24 in the case of ``default_face_cascade`` ), if ``scale`` =2, a two times larger window is used (48x48 in the case of default face cascade). While this will speed-up search about four times, faces smaller than 48x48 cannot be detected - - - -The function assigns images and/or window scale to the hidden classifier cascade. If image pointers are NULL, the previously set images are used further (i.e. NULLs mean "do not change images"). Scale parameter has no such a "protection" value, but the previous value can be retrieved by the -:ref:`GetHaarClassifierCascadeScale` -function and reused again. The function is used to prepare cascade for detecting object of the particular size in the particular image. The function is called internally by -:ref:`HaarDetectObjects` -, but it can be called by the user if they are using the lower-level function -:ref:`RunHaarClassifierCascade` -. - - -.. index:: ReleaseHaarClassifierCascade - -.. _ReleaseHaarClassifierCascade: - -ReleaseHaarClassifierCascade ----------------------------- - - - - - - -.. cfunction:: void cvReleaseHaarClassifierCascade( CvHaarClassifierCascade** cascade ) - - Releases the haar classifier cascade. - - - - - - - :param cascade: Double pointer to the released cascade. The pointer is cleared by the function - - - -The function deallocates the cascade that has been created manually or loaded using -:ref:`LoadHaarClassifierCascade` -or -:ref:`Load` -. - - -.. index:: RunHaarClassifierCascade - -.. _RunHaarClassifierCascade: - -RunHaarClassifierCascade ------------------------- - - - - - - -.. cfunction:: int cvRunHaarClassifierCascade( CvHaarClassifierCascade* cascade, CvPoint pt, int start_stage=0 ) - - Runs a cascade of boosted classifiers at the given image location. - - - - - - - :param cascade: Haar classifier cascade - - - :param pt: Top-left corner of the analyzed region. Size of the region is a original window size scaled by the currenly set scale. The current window size may be retrieved using the :ref:`GetHaarClassifierCascadeWindowSize` function - - - :param start_stage: Initial zero-based index of the cascade stage to start from. The function assumes that all the previous stages are passed. This feature is used internally by :ref:`HaarDetectObjects` for better processor cache utilization - - - -The function runs the Haar classifier -cascade at a single image location. Before using this function the -integral images and the appropriate scale (window size) should be set -using -:ref:`SetImagesForHaarClassifierCascade` -. The function returns -a positive value if the analyzed rectangle passed all the classifier stages -(it is a candidate) and a zero or negative value otherwise. - diff --git a/doc/opencv1/c/video.rst b/doc/opencv1/c/video.rst deleted file mode 100644 index 5c1c79baa4..0000000000 --- a/doc/opencv1/c/video.rst +++ /dev/null @@ -1,10 +0,0 @@ -********************* -video. Video Analysis -********************* - - - -.. toctree:: - :maxdepth: 2 - - video_motion_analysis_and_object_tracking diff --git a/doc/opencv1/c/video_motion_analysis_and_object_tracking.rst b/doc/opencv1/c/video_motion_analysis_and_object_tracking.rst deleted file mode 100644 index 2ae36684df..0000000000 --- a/doc/opencv1/c/video_motion_analysis_and_object_tracking.rst +++ /dev/null @@ -1,1247 +0,0 @@ -Motion Analysis and Object Tracking -=================================== - -.. highlight:: c - - - -.. index:: CalcGlobalOrientation - -.. _CalcGlobalOrientation: - -CalcGlobalOrientation ---------------------- - - - - - - -.. cfunction:: double cvCalcGlobalOrientation( const CvArr* orientation, const CvArr* mask, const CvArr* mhi, double timestamp, double duration ) - - Calculates the global motion orientation of some selected region. - - - - - - - :param orientation: Motion gradient orientation image; calculated by the function :ref:`CalcMotionGradient` - - - :param mask: Mask image. It may be a conjunction of a valid gradient mask, obtained with :ref:`CalcMotionGradient` and the mask of the region, whose direction needs to be calculated - - - :param mhi: Motion history image - - - :param timestamp: Current time in milliseconds or other units, it is better to store time passed to :ref:`UpdateMotionHistory` before and reuse it here, because running :ref:`UpdateMotionHistory` and :ref:`CalcMotionGradient` on large images may take some time - - - :param duration: Maximal duration of motion track in milliseconds, the same as :ref:`UpdateMotionHistory` - - - -The function calculates the general -motion direction in the selected region and returns the angle between -0 degrees and 360 degrees . At first the function builds the orientation histogram -and finds the basic orientation as a coordinate of the histogram -maximum. After that the function calculates the shift relative to the -basic orientation as a weighted sum of all of the orientation vectors: the more -recent the motion, the greater the weight. The resultant angle is -a circular sum of the basic orientation and the shift. - - -.. index:: CalcMotionGradient - -.. _CalcMotionGradient: - -CalcMotionGradient ------------------- - - - - - - -.. cfunction:: void cvCalcMotionGradient( const CvArr* mhi, CvArr* mask, CvArr* orientation, double delta1, double delta2, int apertureSize=3 ) - - Calculates the gradient orientation of a motion history image. - - - - - - - :param mhi: Motion history image - - - :param mask: Mask image; marks pixels where the motion gradient data is correct; output parameter - - - :param orientation: Motion gradient orientation image; contains angles from 0 to ~360 degrees - - - :param delta1: See below - - - :param delta2: See below - - - :param apertureSize: Aperture size of derivative operators used by the function: CV _ SCHARR, 1, 3, 5 or 7 (see :ref:`Sobel` ) - - - -The function calculates the derivatives -:math:`Dx` -and -:math:`Dy` -of -``mhi`` -and then calculates gradient orientation as: - - - -.. math:: - - \texttt{orientation} (x,y)= \arctan{\frac{Dy(x,y)}{Dx(x,y)}} - - -where both -:math:`Dx(x,y)` -and -:math:`Dy(x,y)` -signs are taken into account (as in the -:ref:`CartToPolar` -function). After that -``mask`` -is filled to indicate where the orientation is valid (see the -``delta1`` -and -``delta2`` -description). - -The function finds the minimum ( -:math:`m(x,y)` -) and maximum ( -:math:`M(x,y)` -) mhi values over each pixel -:math:`(x,y)` -neighborhood and assumes the gradient is valid only if - - -.. math:: - - \min ( \texttt{delta1} , \texttt{delta2} ) \le M(x,y)-m(x,y) \le \max ( \texttt{delta1} , \texttt{delta2} ). - - - -.. index:: CalcOpticalFlowBM - -.. _CalcOpticalFlowBM: - -CalcOpticalFlowBM ------------------ - - - - - - -.. cfunction:: void cvCalcOpticalFlowBM( const CvArr* prev, const CvArr* curr, CvSize blockSize, CvSize shiftSize, CvSize max_range, int usePrevious, CvArr* velx, CvArr* vely ) - - Calculates the optical flow for two images by using the block matching method. - - - - - - - :param prev: First image, 8-bit, single-channel - - - :param curr: Second image, 8-bit, single-channel - - - :param blockSize: Size of basic blocks that are compared - - - :param shiftSize: Block coordinate increments - - - :param max_range: Size of the scanned neighborhood in pixels around the block - - - :param usePrevious: Uses the previous (input) velocity field - - - :param velx: Horizontal component of the optical flow of - - .. math:: - - \left \lfloor \frac{\texttt{prev->width} - \texttt{blockSize.width}}{\texttt{shiftSize.width}} \right \rfloor \times \left \lfloor \frac{\texttt{prev->height} - \texttt{blockSize.height}}{\texttt{shiftSize.height}} \right \rfloor - - size, 32-bit floating-point, single-channel - - - :param vely: Vertical component of the optical flow of the same size ``velx`` , 32-bit floating-point, single-channel - - - -The function calculates the optical -flow for overlapped blocks -:math:`\texttt{blockSize.width} \times \texttt{blockSize.height}` -pixels each, thus the velocity -fields are smaller than the original images. For every block in -``prev`` -the functions tries to find a similar block in -``curr`` -in some neighborhood of the original block or shifted by (velx(x0,y0),vely(x0,y0)) block as has been calculated by previous -function call (if -``usePrevious=1`` -) - - -.. index:: CalcOpticalFlowHS - -.. _CalcOpticalFlowHS: - -CalcOpticalFlowHS ------------------ - - - - - - -.. cfunction:: void cvCalcOpticalFlowHS( const CvArr* prev, const CvArr* curr, int usePrevious, CvArr* velx, CvArr* vely, double lambda, CvTermCriteria criteria ) - - Calculates the optical flow for two images. - - - - - - - :param prev: First image, 8-bit, single-channel - - - :param curr: Second image, 8-bit, single-channel - - - :param usePrevious: Uses the previous (input) velocity field - - - :param velx: Horizontal component of the optical flow of the same size as input images, 32-bit floating-point, single-channel - - - :param vely: Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel - - - :param lambda: Lagrangian multiplier - - - :param criteria: Criteria of termination of velocity computing - - - -The function computes the flow for every pixel of the first input image using the Horn and Schunck algorithm -Horn81 -. - - -.. index:: CalcOpticalFlowLK - -.. _CalcOpticalFlowLK: - -CalcOpticalFlowLK ------------------ - - - - - - -.. cfunction:: void cvCalcOpticalFlowLK( const CvArr* prev, const CvArr* curr, CvSize winSize, CvArr* velx, CvArr* vely ) - - Calculates the optical flow for two images. - - - - - - - :param prev: First image, 8-bit, single-channel - - - :param curr: Second image, 8-bit, single-channel - - - :param winSize: Size of the averaging window used for grouping pixels - - - :param velx: Horizontal component of the optical flow of the same size as input images, 32-bit floating-point, single-channel - - - :param vely: Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel - - - -The function computes the flow for every pixel of the first input image using the Lucas and Kanade algorithm -Lucas81 -. - - -.. index:: CalcOpticalFlowPyrLK - -.. _CalcOpticalFlowPyrLK: - -CalcOpticalFlowPyrLK --------------------- - - - - - - -.. cfunction:: void cvCalcOpticalFlowPyrLK( const CvArr* prev, const CvArr* curr, CvArr* prevPyr, CvArr* currPyr, const CvPoint2D32f* prevFeatures, CvPoint2D32f* currFeatures, int count, CvSize winSize, int level, char* status, float* track_error, CvTermCriteria criteria, int flags ) - - Calculates the optical flow for a sparse feature set using the iterative Lucas-Kanade method with pyramids. - - - - - - - :param prev: First frame, at time ``t`` - - - :param curr: Second frame, at time ``t + dt`` - - - :param prevPyr: Buffer for the pyramid for the first frame. If the pointer is not ``NULL`` , the buffer must have a sufficient size to store the pyramid from level ``1`` to level ``level`` ; the total size of ``(image_width+8)*image_height/3`` bytes is sufficient - - - :param currPyr: Similar to ``prevPyr`` , used for the second frame - - - :param prevFeatures: Array of points for which the flow needs to be found - - - :param currFeatures: Array of 2D points containing the calculated new positions of the input features in the second image - - - :param count: Number of feature points - - - :param winSize: Size of the search window of each pyramid level - - - :param level: Maximal pyramid level number. If ``0`` , pyramids are not used (single level), if ``1`` , two levels are used, etc - - - :param status: Array. Every element of the array is set to ``1`` if the flow for the corresponding feature has been found, ``0`` otherwise - - - :param track_error: Array of double numbers containing the difference between patches around the original and moved points. Optional parameter; can be ``NULL`` - - - :param criteria: Specifies when the iteration process of finding the flow for each point on each pyramid level should be stopped - - - :param flags: Miscellaneous flags: - - - * **CV_LKFLOWPyr_A_READY** pyramid for the first frame is precalculated before the call - - - * **CV_LKFLOWPyr_B_READY** pyramid for the second frame is precalculated before the call - - - * **CV_LKFLOW_INITIAL_GUESSES** array B contains initial coordinates of features before the function call - - - - - -The function implements the sparse iterative version of the Lucas-Kanade optical flow in pyramids -Bouguet00 -. It calculates the coordinates of the feature points on the current video -frame given their coordinates on the previous frame. The function finds -the coordinates with sub-pixel accuracy. - -Both parameters -``prevPyr`` -and -``currPyr`` -comply with the -following rules: if the image pointer is 0, the function allocates the -buffer internally, calculates the pyramid, and releases the buffer after -processing. Otherwise, the function calculates the pyramid and stores -it in the buffer unless the flag -``CV_LKFLOWPyr_A[B]_READY`` -is set. The image should be large enough to fit the Gaussian pyramid -data. After the function call both pyramids are calculated and the -readiness flag for the corresponding image can be set in the next call -(i.e., typically, for all the image pairs except the very first one -``CV_LKFLOWPyr_A_READY`` -is set). - - - -.. index:: CamShift - -.. _CamShift: - -CamShift --------- - - - - - - -.. cfunction:: int cvCamShift( const CvArr* prob_image, CvRect window, CvTermCriteria criteria, CvConnectedComp* comp, CvBox2D* box=NULL ) - - Finds the object center, size, and orientation. - - - - - - - :param prob_image: Back projection of object histogram (see :ref:`CalcBackProject` ) - - - :param window: Initial search window - - - :param criteria: Criteria applied to determine when the window search should be finished - - - :param comp: Resultant structure that contains the converged search window coordinates ( ``comp->rect`` field) and the sum of all of the pixels inside the window ( ``comp->area`` field) - - - :param box: Circumscribed box for the object. If not ``NULL`` , it contains object size and orientation - - - -The function implements the CAMSHIFT object tracking algrorithm -Bradski98 -. -First, it finds an object center using -:ref:`MeanShift` -and, after that, calculates the object size and orientation. The function returns number of iterations made within -:ref:`MeanShift` -. - -The -``CamShiftTracker`` -class declared in cv.hpp implements the color object tracker that uses the function. - - -CvConDensation --------------- - - -ConDenstation state. - - - - -:: - - - - typedef struct CvConDensation - { - int MP; //Dimension of measurement vector - int DP; // Dimension of state vector - float* DynamMatr; // Matrix of the linear Dynamics system - float* State; // Vector of State - int SamplesNum; // Number of the Samples - float** flSamples; // array of the Sample Vectors - float** flNewSamples; // temporary array of the Sample Vectors - float* flConfidence; // Confidence for each Sample - float* flCumulative; // Cumulative confidence - float* Temp; // Temporary vector - float* RandomSample; // RandomVector to update sample set - CvRandState* RandS; // Array of structures to generate random vectors - } CvConDensation; - - - -.. - -The structure -``CvConDensation`` -stores the CONditional DENSity propagATION tracker state. The information about the algorithm can be found at -http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/ISARD1/condensation.html -. - - -.. index:: CreateConDensation - -.. _CreateConDensation: - -CreateConDensation ------------------- - - - - - - -.. cfunction:: CvConDensation* cvCreateConDensation( int dynam_params, int measure_params, int sample_count ) - - Allocates the ConDensation filter structure. - - - - - - - :param dynam_params: Dimension of the state vector - - - :param measure_params: Dimension of the measurement vector - - - :param sample_count: Number of samples - - - -The function creates a -``CvConDensation`` -structure and returns a pointer to the structure. - - -.. index:: ConDensInitSampleSet - -.. _ConDensInitSampleSet: - -ConDensInitSampleSet --------------------- - - - - - - -.. cfunction:: void cvConDensInitSampleSet( CvConDensation* condens, CvMat* lower_bound, CvMat* upper_bound ) - - Initializes the sample set for the ConDensation algorithm. - - - - - - - :param condens: Pointer to a structure to be initialized - - - :param lower_bound: Vector of the lower boundary for each dimension - - - :param upper_bound: Vector of the upper boundary for each dimension - - - -The function fills the samples arrays in the structure -``condens`` -with values within the specified ranges. - -.. index:: CvKalman - -.. _CvKalman: - -CvKalman --------- - - - -.. ctype:: CvKalman - - - -Kalman filter state. - - - - -:: - - - - typedef struct CvKalman - { - int MP; /* number of measurement vector dimensions */ - int DP; /* number of state vector dimensions */ - int CP; /* number of control vector dimensions */ - - /* backward compatibility fields */ - #if 1 - float* PosterState; /* =state_pre->data.fl */ - float* PriorState; /* =state_post->data.fl */ - float* DynamMatr; /* =transition_matrix->data.fl */ - float* MeasurementMatr; /* =measurement_matrix->data.fl */ - float* MNCovariance; /* =measurement_noise_cov->data.fl */ - float* PNCovariance; /* =process_noise_cov->data.fl */ - float* KalmGainMatr; /* =gain->data.fl */ - float* PriorErrorCovariance;/* =error_cov_pre->data.fl */ - float* PosterErrorCovariance;/* =error_cov_post->data.fl */ - float* Temp1; /* temp1->data.fl */ - float* Temp2; /* temp2->data.fl */ - #endif - - CvMat* state_pre; /* predicted state (x'(k)): - x(k)=A*x(k-1)+B*u(k) */ - CvMat* state_post; /* corrected state (x(k)): - x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) */ - CvMat* transition_matrix; /* state transition matrix (A) */ - CvMat* control_matrix; /* control matrix (B) - (it is not used if there is no control)*/ - CvMat* measurement_matrix; /* measurement matrix (H) */ - CvMat* process_noise_cov; /* process noise covariance matrix (Q) */ - CvMat* measurement_noise_cov; /* measurement noise covariance matrix (R) */ - CvMat* error_cov_pre; /* priori error estimate covariance matrix (P'(k)): - P'(k)=A*P(k-1)*At + Q*/ - CvMat* gain; /* Kalman gain matrix (K(k)): - K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)*/ - CvMat* error_cov_post; /* posteriori error estimate covariance matrix (P(k)): - P(k)=(I-K(k)*H)*P'(k) */ - CvMat* temp1; /* temporary matrices */ - CvMat* temp2; - CvMat* temp3; - CvMat* temp4; - CvMat* temp5; - } - CvKalman; - - -.. - -The structure -``CvKalman`` -is used to keep the Kalman filter -state. It is created by the -:ref:`CreateKalman` -function, updated -by the -:ref:`KalmanPredict` -and -:ref:`KalmanCorrect` -functions -and released by the -:ref:`ReleaseKalman` -function -. Normally, the -structure is used for the standard Kalman filter (notation and the -formulas below are borrowed from the excellent Kalman tutorial -Welch95 -) - - - -.. math:: - - \begin{array}{l} x_k=A \cdot x_{k-1}+B \cdot u_k+w_k \\ z_k=H \cdot x_k+v_k \end{array} - - -where: - - - -.. math:: - - \begin{array}{l l} x_k \; (x_{k-1})& \text{state of the system at the moment \emph{k} (\emph{k-1})} \\ z_k & \text{measurement of the system state at the moment \emph{k}} \\ u_k & \text{external control applied at the moment \emph{k}} \end{array} - - -:math:`w_k` -and -:math:`v_k` -are normally-distributed process and measurement noise, respectively: - - - -.. math:: - - \begin{array}{l} p(w) \sim N(0,Q) \\ p(v) \sim N(0,R) \end{array} - - -that is, - -:math:`Q` -process noise covariance matrix, constant or variable, - -:math:`R` -measurement noise covariance matrix, constant or variable - -In the case of the standard Kalman filter, all of the matrices: A, B, H, Q and R are initialized once after the -:ref:`CvKalman` -structure is allocated via -:ref:`CreateKalman` -. However, the same structure and the same functions may be used to simulate the extended Kalman filter by linearizing the extended Kalman filter equation in the current system state neighborhood, in this case A, B, H (and, probably, Q and R) should be updated on every step. - - -.. index:: CreateKalman - -.. _CreateKalman: - -CreateKalman ------------- - - - - - - -.. cfunction:: CvKalman* cvCreateKalman( int dynam_params, int measure_params, int control_params=0 ) - - Allocates the Kalman filter structure. - - - - - - - :param dynam_params: dimensionality of the state vector - - - :param measure_params: dimensionality of the measurement vector - - - :param control_params: dimensionality of the control vector - - - -The function allocates -:ref:`CvKalman` -and all its matrices and initializes them somehow. - - - -.. index:: KalmanCorrect - -.. _KalmanCorrect: - -KalmanCorrect -------------- - - - - - - -.. cfunction:: const CvMat* cvKalmanCorrect( CvKalman* kalman, const CvMat* measurement ) - - Adjusts the model state. - - - - - - - :param kalman: Pointer to the structure to be updated - - - :param measurement: CvMat containing the measurement vector - - - -The function adjusts the stochastic model state on the basis of the given measurement of the model state: - - - -.. math:: - - \begin{array}{l} K_k=P'_k \cdot H^T \cdot (H \cdot P'_k \cdot H^T+R)^{-1} \\ x_k=x'_k+K_k \cdot (z_k-H \cdot x'_k) \\ P_k=(I-K_k \cdot H) \cdot P'_k \end{array} - - -where - - -.. table:: - - =========== =============================================== - :math:`z_k` given measurement ( ``mesurement`` parameter) \ - =========== =============================================== - :math:`K_k` Kalman "gain" matrix. \ - =========== =============================================== - -The function stores the adjusted state at -``kalman->state_post`` -and returns it on output. - -Example. Using Kalman filter to track a rotating point - - - -:: - - - - #include "cv.h" - #include "highgui.h" - #include - - int main(int argc, char** argv) - { - /* A matrix data */ - const float A[] = { 1, 1, 0, 1 }; - - IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 ); - CvKalman* kalman = cvCreateKalman( 2, 1, 0 ); - /* state is (phi, delta_phi) - angle and angle increment */ - CvMat* state = cvCreateMat( 2, 1, CV_32FC1 ); - CvMat* process_noise = cvCreateMat( 2, 1, CV_32FC1 ); - /* only phi (angle) is measured */ - CvMat* measurement = cvCreateMat( 1, 1, CV_32FC1 ); - CvRandState rng; - int code = -1; - - cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI ); - - cvZero( measurement ); - cvNamedWindow( "Kalman", 1 ); - - for(;;) - { - cvRandSetRange( &rng, 0, 0.1, 0 ); - rng.disttype = CV_RAND_NORMAL; - - cvRand( &rng, state ); - - memcpy( kalman->transition_matrix->data.fl, A, sizeof(A)); - cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) ); - cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) ); - cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(1e-1) ); - cvSetIdentity( kalman->error_cov_post, cvRealScalar(1)); - /* choose random initial state */ - cvRand( &rng, kalman->state_post ); - - rng.disttype = CV_RAND_NORMAL; - - for(;;) - { - #define calc_point(angle) \ - cvPoint( cvRound(img->width/2 + img->width/3*cos(angle)), \ - cvRound(img->height/2 - img->width/3*sin(angle))) - - float state_angle = state->data.fl[0]; - CvPoint state_pt = calc_point(state_angle); - - /* predict point position */ - const CvMat* prediction = cvKalmanPredict( kalman, 0 ); - float predict_angle = prediction->data.fl[0]; - CvPoint predict_pt = calc_point(predict_angle); - float measurement_angle; - CvPoint measurement_pt; - - cvRandSetRange( &rng, - 0, - sqrt(kalman->measurement_noise_cov->data.fl[0]), - 0 ); - cvRand( &rng, measurement ); - - /* generate measurement */ - cvMatMulAdd( kalman->measurement_matrix, state, measurement, measurement ); - - measurement_angle = measurement->data.fl[0]; - measurement_pt = calc_point(measurement_angle); - - /* plot points */ - #define draw_cross( center, color, d ) \ - cvLine( img, cvPoint( center.x - d, center.y - d ), \ - cvPoint( center.x + d, center.y + d ), \ - color, 1, 0 ); \ - cvLine( img, cvPoint( center.x + d, center.y - d ), \ - cvPoint( center.x - d, center.y + d ), \ - color, 1, 0 ) - - cvZero( img ); - draw_cross( state_pt, CV_RGB(255,255,255), 3 ); - draw_cross( measurement_pt, CV_RGB(255,0,0), 3 ); - draw_cross( predict_pt, CV_RGB(0,255,0), 3 ); - cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, 0 ); - - /* adjust Kalman filter state */ - cvKalmanCorrect( kalman, measurement ); - - cvRandSetRange( &rng, - 0, - sqrt(kalman->process_noise_cov->data.fl[0]), - 0 ); - cvRand( &rng, process_noise ); - cvMatMulAdd( kalman->transition_matrix, - state, - process_noise, - state ); - - cvShowImage( "Kalman", img ); - code = cvWaitKey( 100 ); - - if( code > 0 ) /* break current simulation by pressing a key */ - break; - } - if( code == 27 ) /* exit by ESCAPE */ - break; - } - - return 0; - } - - -.. - - -.. index:: KalmanPredict - -.. _KalmanPredict: - -KalmanPredict -------------- - - - - - - -.. cfunction:: const CvMat* cvKalmanPredict( CvKalman* kalman, const CvMat* control=NULL) - - Estimates the subsequent model state. - - - - - - - :param kalman: Kalman filter state - - - :param control: Control vector :math:`u_k` , should be NULL iff there is no external control ( ``control_params`` =0) - - - -The function estimates the subsequent stochastic model state by its current state and stores it at -``kalman->state_pre`` -: - - - -.. math:: - - \begin{array}{l} x'_k=A x_{k-1} + B u_k \\ P'_k=A P_{k-1} A^T + Q \end{array} - - -where - - -.. table:: - - =============== ==================================================================================================================================================================== - :math:`x'_k` is predicted state ``kalman->state_pre`` , \ - =============== ==================================================================================================================================================================== - :math:`x_{k-1}` is corrected state on the previous step ``kalman->state_post`` (should be initialized somehow in the beginning, zero vector by default), \ - :math:`u_k` is external control ( ``control`` parameter), \ - :math:`P'_k` is priori error covariance matrix ``kalman->error_cov_pre`` \ - :math:`P_{k-1}` is posteriori error covariance matrix on the previous step ``kalman->error_cov_post`` (should be initialized somehow in the beginning, identity matrix by default), - =============== ==================================================================================================================================================================== - -The function returns the estimated state. - - -KalmanUpdateByMeasurement -------------------------- - - -Synonym for -:ref:`KalmanCorrect` - -KalmanUpdateByTime ------------------- - - -Synonym for -:ref:`KalmanPredict` - -.. index:: MeanShift - -.. _MeanShift: - -MeanShift ---------- - - - - - - -.. cfunction:: int cvMeanShift( const CvArr* prob_image, CvRect window, CvTermCriteria criteria, CvConnectedComp* comp ) - - Finds the object center on back projection. - - - - - - - :param prob_image: Back projection of the object histogram (see :ref:`CalcBackProject` ) - - - :param window: Initial search window - - - :param criteria: Criteria applied to determine when the window search should be finished - - - :param comp: Resultant structure that contains the converged search window coordinates ( ``comp->rect`` field) and the sum of all of the pixels inside the window ( ``comp->area`` field) - - - -The function iterates to find the object center -given its back projection and initial position of search window. The -iterations are made until the search window center moves by less than -the given value and/or until the function has done the maximum number -of iterations. The function returns the number of iterations made. - - -.. index:: ReleaseConDensation - -.. _ReleaseConDensation: - -ReleaseConDensation -------------------- - - - - - - -.. cfunction:: void cvReleaseConDensation( CvConDensation** condens ) - - Deallocates the ConDensation filter structure. - - - - - - - :param condens: Pointer to the pointer to the structure to be released - - - -The function releases the structure -``condens`` -) and frees all memory previously allocated for the structure. - - -.. index:: ReleaseKalman - -.. _ReleaseKalman: - -ReleaseKalman -------------- - - - - - - -.. cfunction:: void cvReleaseKalman( CvKalman** kalman ) - - Deallocates the Kalman filter structure. - - - - - - - :param kalman: double pointer to the Kalman filter structure - - - -The function releases the structure -:ref:`CvKalman` -and all of the underlying matrices. - - -.. index:: SegmentMotion - -.. _SegmentMotion: - -SegmentMotion -------------- - - - - - - -.. cfunction:: CvSeq* cvSegmentMotion( const CvArr* mhi, CvArr* seg_mask, CvMemStorage* storage, double timestamp, double seg_thresh ) - - Segments a whole motion into separate moving parts. - - - - - - - :param mhi: Motion history image - - - :param seg_mask: Image where the mask found should be stored, single-channel, 32-bit floating-point - - - :param storage: Memory storage that will contain a sequence of motion connected components - - - :param timestamp: Current time in milliseconds or other units - - - :param seg_thresh: Segmentation threshold; recommended to be equal to the interval between motion history "steps" or greater - - - -The function finds all of the motion segments and -marks them in -``seg_mask`` -with individual values (1,2,...). It -also returns a sequence of -:ref:`CvConnectedComp` -structures, one for each motion component. After that the -motion direction for every component can be calculated with -:ref:`CalcGlobalOrientation` -using the extracted mask of the particular -component -:ref:`Cmp` -. - - -.. index:: SnakeImage - -.. _SnakeImage: - -SnakeImage ----------- - - - - - - -.. cfunction:: void cvSnakeImage( const IplImage* image, CvPoint* points, int length, float* alpha, float* beta, float* gamma, int coeff_usage, CvSize win, CvTermCriteria criteria, int calc_gradient=1 ) - - Changes the contour position to minimize its energy. - - - - - - - :param image: The source image or external energy field - - - :param points: Contour points (snake) - - - :param length: Number of points in the contour - - - :param alpha: Weight[s] of continuity energy, single float or - array of ``length`` floats, one for each contour point - - - :param beta: Weight[s] of curvature energy, similar to ``alpha`` - - - :param gamma: Weight[s] of image energy, similar to ``alpha`` - - - :param coeff_usage: Different uses of the previous three parameters: - - - * **CV_VALUE** indicates that each of ``alpha, beta, gamma`` is a pointer to a single value to be used for all points; - - - * **CV_ARRAY** indicates that each of ``alpha, beta, gamma`` is a pointer to an array of coefficients different for all the points of the snake. All the arrays must have the size equal to the contour size. - - - - - :param win: Size of neighborhood of every point used to search the minimum, both ``win.width`` and ``win.height`` must be odd - - - :param criteria: Termination criteria - - - :param calc_gradient: Gradient flag; if not 0, the function calculates the gradient magnitude for every image pixel and consideres it as the energy field, otherwise the input image itself is considered - - - -The function updates the snake in order to minimize its -total energy that is a sum of internal energy that depends on the contour -shape (the smoother contour is, the smaller internal energy is) and -external energy that depends on the energy field and reaches minimum at -the local energy extremums that correspond to the image edges in the case -of using an image gradient. - -The parameter -``criteria.epsilon`` -is used to define the minimal -number of points that must be moved during any iteration to keep the -iteration process running. - -If at some iteration the number of moved points is less -than -``criteria.epsilon`` -or the function performed -``criteria.max_iter`` -iterations, the function terminates. - - -.. index:: UpdateMotionHistory - -.. _UpdateMotionHistory: - -UpdateMotionHistory -------------------- - - - - - - -.. cfunction:: void cvUpdateMotionHistory( const CvArr* silhouette, CvArr* mhi, double timestamp, double duration ) - - Updates the motion history image by a moving silhouette. - - - - - - - :param silhouette: Silhouette mask that has non-zero pixels where the motion occurs - - - :param mhi: Motion history image, that is updated by the function (single-channel, 32-bit floating-point) - - - :param timestamp: Current time in milliseconds or other units - - - :param duration: Maximal duration of the motion track in the same units as ``timestamp`` - - - -The function updates the motion history image as following: - - - -.. math:: - - \texttt{mhi} (x,y)= \forkthree{\texttt{timestamp}}{if $\texttt{silhouette}(x,y) \ne 0$}{0}{if $\texttt{silhouette}(x,y) = 0$ and $\texttt{mhi} < (\texttt{timestamp} - \texttt{duration})$}{\texttt{mhi}(x,y)}{otherwise} - - -That is, MHI pixels where motion occurs are set to the current timestamp, while the pixels where motion happened far ago are cleared. - diff --git a/doc/opencv1/py/calib3d.rst b/doc/opencv1/py/calib3d.rst deleted file mode 100644 index 5dcd6768de..0000000000 --- a/doc/opencv1/py/calib3d.rst +++ /dev/null @@ -1,10 +0,0 @@ -******************************************************* -calib3d. Camera Calibration, Pose Estimation and Stereo -******************************************************* - - - -.. toctree:: - :maxdepth: 2 - - calib3d_camera_calibration_and_3d_reconstruction diff --git a/doc/opencv1/py/calib3d_camera_calibration_and_3d_reconstruction.rst b/doc/opencv1/py/calib3d_camera_calibration_and_3d_reconstruction.rst deleted file mode 100644 index 5ba8a9279d..0000000000 --- a/doc/opencv1/py/calib3d_camera_calibration_and_3d_reconstruction.rst +++ /dev/null @@ -1,2644 +0,0 @@ -Camera Calibration and 3d Reconstruction -======================================== - -.. highlight:: python - - -The functions in this section use the so-called pinhole camera model. That -is, a scene view is formed by projecting 3D points into the image plane -using a perspective transformation. - - - -.. math:: - - s \; m' = A [R|t] M' - - -or - - - -.. math:: - - s \vecthree{u}{v}{1} = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1} \begin{bmatrix} r_{11} & r_{12} & r_{13} & t_1 \\ r_{21} & r_{22} & r_{23} & t_2 \\ r_{31} & r_{32} & r_{33} & t_3 \end{bmatrix} \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix} - - -Where -:math:`(X, Y, Z)` -are the coordinates of a 3D point in the world -coordinate space, -:math:`(u, v)` -are the coordinates of the projection point -in pixels. -:math:`A` -is called a camera matrix, or a matrix of -intrinsic parameters. -:math:`(cx, cy)` -is a principal point (that is -usually at the image center), and -:math:`fx, fy` -are the focal lengths -expressed in pixel-related units. Thus, if an image from camera is -scaled by some factor, all of these parameters should -be scaled (multiplied/divided, respectively) by the same factor. The -matrix of intrinsic parameters does not depend on the scene viewed and, -once estimated, can be re-used (as long as the focal length is fixed (in -case of zoom lens)). The joint rotation-translation matrix -:math:`[R|t]` -is called a matrix of extrinsic parameters. It is used to describe the -camera motion around a static scene, or vice versa, rigid motion of an -object in front of still camera. That is, -:math:`[R|t]` -translates -coordinates of a point -:math:`(X, Y, Z)` -to some coordinate system, -fixed with respect to the camera. The transformation above is equivalent -to the following (when -:math:`z \ne 0` -): - - - -.. math:: - - \begin{array}{l} \vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\ x' = x/z \\ y' = y/z \\ u = f_x*x' + c_x \\ v = f_y*y' + c_y \end{array} - - -Real lenses usually have some distortion, mostly -radial distortion and slight tangential distortion. So, the above model -is extended as: - - - -.. math:: - - \begin{array}{l} \vecthree{x}{y}{z} = R \vecthree{X}{Y}{Z} + t \\ x' = x/z \\ y' = y/z \\ x'' = x' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + 2 p_1 x' y' + p_2(r^2 + 2 x'^2) \\ y'' = y' \frac{1 + k_1 r^2 + k_2 r^4 + k_3 r^6}{1 + k_4 r^2 + k_5 r^4 + k_6 r^6} + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' \\ \text{where} \quad r^2 = x'^2 + y'^2 \\ u = f_x*x'' + c_x \\ v = f_y*y'' + c_y \end{array} - - -:math:`k_1` -, -:math:`k_2` -, -:math:`k_3` -, -:math:`k_4` -, -:math:`k_5` -, -:math:`k_6` -are radial distortion coefficients, -:math:`p_1` -, -:math:`p_2` -are tangential distortion coefficients. -Higher-order coefficients are not considered in OpenCV. In the functions below the coefficients are passed or returned as - - -.. math:: - - (k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]]) - - -vector. That is, if the vector contains 4 elements, it means that -:math:`k_3=0` -. -The distortion coefficients do not depend on the scene viewed, thus they also belong to the intrinsic camera parameters. -*And they remain the same regardless of the captured image resolution.* -That is, if, for example, a camera has been calibrated on images of -:math:`320 -\times 240` -resolution, absolutely the same distortion coefficients can -be used for images of -:math:`640 \times 480` -resolution from the same camera (while -:math:`f_x` -, -:math:`f_y` -, -:math:`c_x` -and -:math:`c_y` -need to be scaled appropriately). - -The functions below use the above model to - - - - - -* - Project 3D points to the image plane given intrinsic and extrinsic parameters - - - -* - Compute extrinsic parameters given intrinsic parameters, a few 3D points and their projections. - - - -* - Estimate intrinsic and extrinsic camera parameters from several views of a known calibration pattern (i.e. every view is described by several 3D-2D point correspondences). - - - -* - Estimate the relative position and orientation of the stereo camera "heads" and compute the - *rectification* - transformation that makes the camera optical axes parallel. - - - -.. index:: CalibrateCamera2 - -.. _CalibrateCamera2: - -CalibrateCamera2 ----------------- - - - - -.. function:: CalibrateCamera2(objectPoints,imagePoints,pointCounts,imageSize,cameraMatrix,distCoeffs,rvecs,tvecs,flags=0)-> None - - Finds the camera intrinsic and extrinsic parameters from several views of a calibration pattern. - - - - - - - :param objectPoints: The joint matrix of object points - calibration pattern features in the model coordinate space. It is floating-point 3xN or Nx3 1-channel, or 1xN or Nx1 3-channel array, where N is the total number of points in all views. - - :type objectPoints: :class:`CvMat` - - - :param imagePoints: The joint matrix of object points projections in the camera views. It is floating-point 2xN or Nx2 1-channel, or 1xN or Nx1 2-channel array, where N is the total number of points in all views - - :type imagePoints: :class:`CvMat` - - - :param pointCounts: Integer 1xM or Mx1 vector (where M is the number of calibration pattern views) containing the number of points in each particular view. The sum of vector elements must match the size of ``objectPoints`` and ``imagePoints`` (=N). - - :type pointCounts: :class:`CvMat` - - - :param imageSize: Size of the image, used only to initialize the intrinsic camera matrix - - :type imageSize: :class:`CvSize` - - - :param cameraMatrix: The output 3x3 floating-point camera matrix :math:`A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` . If ``CV_CALIB_USE_INTRINSIC_GUESS`` and/or ``CV_CALIB_FIX_ASPECT_RATIO`` are specified, some or all of ``fx, fy, cx, cy`` must be initialized before calling the function - - :type cameraMatrix: :class:`CvMat` - - - :param distCoeffs: The output vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements - - :type distCoeffs: :class:`CvMat` - - - :param rvecs: The output 3x *M* or *M* x3 1-channel, or 1x *M* or *M* x1 3-channel array of rotation vectors (see :ref:`Rodrigues2` ), estimated for each pattern view. That is, each k-th rotation vector together with the corresponding k-th translation vector (see the next output parameter description) brings the calibration pattern from the model coordinate space (in which object points are specified) to the world coordinate space, i.e. real position of the calibration pattern in the k-th pattern view (k=0.. *M* -1) - - :type rvecs: :class:`CvMat` - - - :param tvecs: The output 3x *M* or *M* x3 1-channel, or 1x *M* or *M* x1 3-channel array of translation vectors, estimated for each pattern view. - - :type tvecs: :class:`CvMat` - - - :param flags: Different flags, may be 0 or combination of the following values: - - * **CV_CALIB_USE_INTRINSIC_GUESS** ``cameraMatrix`` contains the valid initial values of ``fx, fy, cx, cy`` that are optimized further. Otherwise, ``(cx, cy)`` is initially set to the image center ( ``imageSize`` is used here), and focal distances are computed in some least-squares fashion. Note, that if intrinsic parameters are known, there is no need to use this function just to estimate the extrinsic parameters. Use :ref:`FindExtrinsicCameraParams2` instead. - - * **CV_CALIB_FIX_PRINCIPAL_POINT** The principal point is not changed during the global optimization, it stays at the center or at the other location specified when ``CV_CALIB_USE_INTRINSIC_GUESS`` is set too. - - * **CV_CALIB_FIX_ASPECT_RATIO** The functions considers only ``fy`` as a free parameter, the ratio ``fx/fy`` stays the same as in the input ``cameraMatrix`` . When ``CV_CALIB_USE_INTRINSIC_GUESS`` is not set, the actual input values of ``fx`` and ``fy`` are ignored, only their ratio is computed and used further. - - * **CV_CALIB_ZERO_TANGENT_DIST** Tangential distortion coefficients :math:`(p_1, p_2)` will be set to zeros and stay zero. - - - :type flags: int - - - * **CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6** Do not change the corresponding radial distortion coefficient during the optimization. If ``CV_CALIB_USE_INTRINSIC_GUESS`` is set, the coefficient from the supplied ``distCoeffs`` matrix is used, otherwise it is set to 0. - - - * **CV_CALIB_RATIONAL_MODEL** Enable coefficients k4, k5 and k6. To provide the backward compatibility, this extra flag should be explicitly specified to make the calibration function use the rational model and return 8 coefficients. If the flag is not set, the function will compute only 5 distortion coefficients. - - - - - -The function estimates the intrinsic camera -parameters and extrinsic parameters for each of the views. The -coordinates of 3D object points and their correspondent 2D projections -in each view must be specified. That may be achieved by using an -object with known geometry and easily detectable feature points. -Such an object is called a calibration rig or calibration pattern, -and OpenCV has built-in support for a chessboard as a calibration -rig (see -:ref:`FindChessboardCorners` -). Currently, initialization -of intrinsic parameters (when -``CV_CALIB_USE_INTRINSIC_GUESS`` -is not set) is only implemented for planar calibration patterns -(where z-coordinates of the object points must be all 0's). 3D -calibration rigs can also be used as long as initial -``cameraMatrix`` -is provided. - -The algorithm does the following: - - - - -#. - First, it computes the initial intrinsic parameters (the option only available for planar calibration patterns) or reads them from the input parameters. The distortion coefficients are all set to zeros initially (unless some of - ``CV_CALIB_FIX_K?`` - are specified). - - - -#. - The initial camera pose is estimated as if the intrinsic parameters have been already known. This is done using - :ref:`FindExtrinsicCameraParams2` - - -#. - After that the global Levenberg-Marquardt optimization algorithm is run to minimize the reprojection error, i.e. the total sum of squared distances between the observed feature points - ``imagePoints`` - and the projected (using the current estimates for camera parameters and the poses) object points - ``objectPoints`` - ; see - :ref:`ProjectPoints2` - . - - -Note: if you're using a non-square (=non-NxN) grid and -:cpp:func:`findChessboardCorners` -for calibration, and -``calibrateCamera`` -returns -bad values (i.e. zero distortion coefficients, an image center very far from -:math:`(w/2-0.5,h/2-0.5)` -, and / or large differences between -:math:`f_x` -and -:math:`f_y` -(ratios of -10:1 or more)), then you've probably used -``patternSize=cvSize(rows,cols)`` -, -but should use -``patternSize=cvSize(cols,rows)`` -in -:ref:`FindChessboardCorners` -. - -See also: -:ref:`FindChessboardCorners` -, -:ref:`FindExtrinsicCameraParams2` -, -:cpp:func:`initCameraMatrix2D` -, -:ref:`StereoCalibrate` -, -:ref:`Undistort2` - -.. index:: ComputeCorrespondEpilines - -.. _ComputeCorrespondEpilines: - -ComputeCorrespondEpilines -------------------------- - - - - -.. function:: ComputeCorrespondEpilines(points, whichImage, F, lines) -> None - - For points in one image of a stereo pair, computes the corresponding epilines in the other image. - - - - - - - :param points: The input points. ``2xN, Nx2, 3xN`` or ``Nx3`` array (where ``N`` number of points). Multi-channel ``1xN`` or ``Nx1`` array is also acceptable - - :type points: :class:`CvMat` - - - :param whichImage: Index of the image (1 or 2) that contains the ``points`` - - :type whichImage: int - - - :param F: The fundamental matrix that can be estimated using :ref:`FindFundamentalMat` - or :ref:`StereoRectify` . - - :type F: :class:`CvMat` - - - :param lines: The output epilines, a ``3xN`` or ``Nx3`` array. Each line :math:`ax + by + c=0` is encoded by 3 numbers :math:`(a, b, c)` - - :type lines: :class:`CvMat` - - - -For every point in one of the two images of a stereo-pair the function finds the equation of the -corresponding epipolar line in the other image. - -From the fundamental matrix definition (see -:ref:`FindFundamentalMat` -), -line -:math:`l^{(2)}_i` -in the second image for the point -:math:`p^{(1)}_i` -in the first image (i.e. when -``whichImage=1`` -) is computed as: - - - -.. math:: - - l^{(2)}_i = F p^{(1)}_i - - -and, vice versa, when -``whichImage=2`` -, -:math:`l^{(1)}_i` -is computed from -:math:`p^{(2)}_i` -as: - - - -.. math:: - - l^{(1)}_i = F^T p^{(2)}_i - - -Line coefficients are defined up to a scale. They are normalized, such that -:math:`a_i^2+b_i^2=1` -. - - -.. index:: ConvertPointsHomogeneous - -.. _ConvertPointsHomogeneous: - -ConvertPointsHomogeneous ------------------------- - - - - -.. function:: ConvertPointsHomogeneous( src, dst ) -> None - - Convert points to/from homogeneous coordinates. - - - - - - - :param src: The input array or vector of 2D, 3D or 4D points - - :type src: :class:`CvMat` - - - :param dst: The output vector of 2D or 2D points - - :type dst: :class:`CvMat` - - - -The -2D or 3D points from/to homogeneous coordinates, or simply -the array. If the input array dimensionality is larger than the output, each coordinate is divided by the last coordinate: - - - -.. math:: - - \begin{array}{l} (x,y[,z],w) -> (x',y'[,z']) \\ \text{where} \\ x' = x/w \\ y' = y/w \\ z' = z/w \quad \text{(if output is 3D)} \end{array} - - -If the output array dimensionality is larger, an extra 1 is appended to each point. Otherwise, the input array is simply copied (with optional transposition) to the output. - - -.. index:: CreatePOSITObject - -.. _CreatePOSITObject: - -CreatePOSITObject ------------------ - - - - -.. function:: CreatePOSITObject(points)-> POSITObject - - Initializes a structure containing object information. - - - - - - - :param points: List of 3D points - - :type points: :class:`CvPoint3D32fs` - - - -The function allocates memory for the object structure and computes the object inverse matrix. - -The preprocessed object data is stored in the structure -:ref:`CvPOSITObject` -, internal for OpenCV, which means that the user cannot directly access the structure data. The user may only create this structure and pass its pointer to the function. - -An object is defined as a set of points given in a coordinate system. The function -:ref:`POSIT` -computes a vector that begins at a camera-related coordinate system center and ends at the -``points[0]`` -of the object. - -Once the work with a given object is finished, the function -:ref:`ReleasePOSITObject` -must be called to free memory. - - -.. index:: CreateStereoBMState - -.. _CreateStereoBMState: - -CreateStereoBMState -------------------- - - - - -.. function:: CreateStereoBMState(preset=CV_STEREO_BM_BASIC,numberOfDisparities=0)-> StereoBMState - - Creates block matching stereo correspondence structure. - - - - - - - :param preset: ID of one of the pre-defined parameter sets. Any of the parameters can be overridden after creating the structure. Values are - - * **CV_STEREO_BM_BASIC** Parameters suitable for general cameras - - * **CV_STEREO_BM_FISH_EYE** Parameters suitable for wide-angle cameras - - * **CV_STEREO_BM_NARROW** Parameters suitable for narrow-angle cameras - - - - :type preset: int - - - :param numberOfDisparities: The number of disparities. If the parameter is 0, it is taken from the preset, otherwise the supplied value overrides the one from preset. - - :type numberOfDisparities: int - - - -The function creates the stereo correspondence structure and initializes -it. It is possible to override any of the parameters at any time between -the calls to -:ref:`FindStereoCorrespondenceBM` -. - - -.. index:: CreateStereoGCState - -.. _CreateStereoGCState: - -CreateStereoGCState -------------------- - - - - -.. function:: CreateStereoGCState(numberOfDisparities,maxIters)-> StereoGCState - - Creates the state of graph cut-based stereo correspondence algorithm. - - - - - - - :param numberOfDisparities: The number of disparities. The disparity search range will be :math:`\texttt{state->minDisparity} \le disparity < \texttt{state->minDisparity} + \texttt{state->numberOfDisparities}` - - :type numberOfDisparities: int - - - :param maxIters: Maximum number of iterations. On each iteration all possible (or reasonable) alpha-expansions are tried. The algorithm may terminate earlier if it could not find an alpha-expansion that decreases the overall cost function value. See Kolmogorov03 for details. - - :type maxIters: int - - - -The function creates the stereo correspondence structure and initializes it. It is possible to override any of the parameters at any time between the calls to -:ref:`FindStereoCorrespondenceGC` -. - - -.. index:: CvStereoBMState - -.. _CvStereoBMState: - -CvStereoBMState ---------------- - - - -.. class:: CvStereoBMState - - - -The structure for block matching stereo correspondence algorithm. - - - - - - .. attribute:: preFilterType - - - - type of the prefilter, ``CV_STEREO_BM_NORMALIZED_RESPONSE`` or the default and the recommended ``CV_STEREO_BM_XSOBEL`` , int - - - - .. attribute:: preFilterSize - - - - ~5x5..21x21, int - - - - .. attribute:: preFilterCap - - - - up to ~31, int - - - - .. attribute:: SADWindowSize - - - - Could be 5x5..21x21 or higher, but with 21x21 or smaller windows the processing speed is much higher, int - - - - .. attribute:: minDisparity - - - - minimum disparity (=0), int - - - - .. attribute:: numberOfDisparities - - - - maximum disparity - minimum disparity, int - - - - .. attribute:: textureThreshold - - - - the textureness threshold. That is, if the sum of absolute values of x-derivatives computed over ``SADWindowSize`` by ``SADWindowSize`` pixel neighborhood is smaller than the parameter, no disparity is computed at the pixel, int - - - - .. attribute:: uniquenessRatio - - - - the minimum margin in percents between the best (minimum) cost function value and the second best value to accept the computed disparity, int - - - - .. attribute:: speckleWindowSize - - - - the maximum area of speckles to remove (set to 0 to disable speckle filtering), int - - - - .. attribute:: speckleRange - - - - acceptable range of disparity variation in each connected component, int - - - - .. attribute:: trySmallerWindows - - - - not used currently (0), int - - - - .. attribute:: roi1, roi2 - - - - These are the clipping ROIs for the left and the right images. The function :ref:`StereoRectify` returns the largest rectangles in the left and right images where after the rectification all the pixels are valid. If you copy those rectangles to the ``CvStereoBMState`` structure, the stereo correspondence function will automatically clear out the pixels outside of the "valid" disparity rectangle computed by :ref:`GetValidDisparityROI` . Thus you will get more "invalid disparity" pixels than usual, but the remaining pixels are more probable to be valid. - - - - .. attribute:: disp12MaxDiff - - - - The maximum allowed difference between the explicitly computed left-to-right disparity map and the implicitly (by :ref:`ValidateDisparity` ) computed right-to-left disparity. If for some pixel the difference is larger than the specified threshold, the disparity at the pixel is invalidated. By default this parameter is set to (-1), which means that the left-right check is not performed. - - - -The block matching stereo correspondence algorithm, by Kurt Konolige, is very fast single-pass stereo matching algorithm that uses sliding sums of absolute differences between pixels in the left image and the pixels in the right image, shifted by some varying amount of pixels (from -``minDisparity`` -to -``minDisparity+numberOfDisparities`` -). On a pair of images WxH the algorithm computes disparity in -``O(W*H*numberOfDisparities)`` -time. In order to improve quality and readability of the disparity map, the algorithm includes pre-filtering and post-filtering procedures. - -Note that the algorithm searches for the corresponding blocks in x direction only. It means that the supplied stereo pair should be rectified. Vertical stereo layout is not directly supported, but in such a case the images could be transposed by user. - - -.. index:: CvStereoGCState - -.. _CvStereoGCState: - -CvStereoGCState ---------------- - - - -.. class:: CvStereoGCState - - - -The structure for graph cuts-based stereo correspondence algorithm - - - - - - .. attribute:: Ithreshold - - - - threshold for piece-wise linear data cost function (5 by default) - - - - .. attribute:: interactionRadius - - - - radius for smoothness cost function (1 by default; means Potts model) - - - - .. attribute:: K, lambda, lambda1, lambda2 - - - - parameters for the cost function (usually computed adaptively from the input data) - - - - .. attribute:: occlusionCost - - - - 10000 by default - - - - .. attribute:: minDisparity - - - - 0 by default; see :ref:`CvStereoBMState` - - - - .. attribute:: numberOfDisparities - - - - defined by user; see :ref:`CvStereoBMState` - - - - .. attribute:: maxIters - - - - number of iterations; defined by user. - - - -The graph cuts stereo correspondence algorithm, described in -Kolmogorov03 -(as -**KZ1** -), is non-realtime stereo correspondence algorithm that usually gives very accurate depth map with well-defined object boundaries. The algorithm represents stereo problem as a sequence of binary optimization problems, each of those is solved using maximum graph flow algorithm. The state structure above should not be allocated and initialized manually; instead, use -:ref:`CreateStereoGCState` -and then override necessary parameters if needed. - - -.. index:: DecomposeProjectionMatrix - -.. _DecomposeProjectionMatrix: - -DecomposeProjectionMatrix -------------------------- - - - - -.. function:: DecomposeProjectionMatrix(projMatrix, cameraMatrix, rotMatrix, transVect, rotMatrX = None, rotMatrY = None, rotMatrZ = None) -> eulerAngles - - Decomposes the projection matrix into a rotation matrix and a camera matrix. - - - - - - - :param projMatrix: The 3x4 input projection matrix P - - :type projMatrix: :class:`CvMat` - - - :param cameraMatrix: The output 3x3 camera matrix K - - :type cameraMatrix: :class:`CvMat` - - - :param rotMatrix: The output 3x3 external rotation matrix R - - :type rotMatrix: :class:`CvMat` - - - :param transVect: The output 4x1 translation vector T - - :type transVect: :class:`CvMat` - - - :param rotMatrX: Optional 3x3 rotation matrix around x-axis - - :type rotMatrX: :class:`CvMat` - - - :param rotMatrY: Optional 3x3 rotation matrix around y-axis - - :type rotMatrY: :class:`CvMat` - - - :param rotMatrZ: Optional 3x3 rotation matrix around z-axis - - :type rotMatrZ: :class:`CvMat` - - - :param eulerAngles: Optional 3 points containing the three Euler angles of rotation - - :type eulerAngles: :class:`CvPoint3D64f` - - - -The function computes a decomposition of a projection matrix into a calibration and a rotation matrix and the position of the camera. - -It optionally returns three rotation matrices, one for each axis, and the three Euler angles that could be used in OpenGL. - -The function is based on -:ref:`RQDecomp3x3` -. - - -.. index:: DrawChessboardCorners - -.. _DrawChessboardCorners: - -DrawChessboardCorners ---------------------- - - - - -.. function:: DrawChessboardCorners(image,patternSize,corners,patternWasFound)-> None - - Renders the detected chessboard corners. - - - - - - - :param image: The destination image; it must be an 8-bit color image - - :type image: :class:`CvArr` - - - :param patternSize: The number of inner corners per chessboard row and column. (patternSize = cv::Size(points _ per _ row,points _ per _ column) = cv::Size(rows,columns) ) - - :type patternSize: :class:`CvSize` - - - :param corners: The array of corners detected, this should be the output from findChessboardCorners wrapped in a cv::Mat(). - - :type corners: sequence of (float, float) - - - :param patternWasFound: Indicates whether the complete board was found :math:`(\ne 0)` or not :math:`(=0)` . One may just pass the return value :ref:`FindChessboardCorners` here - - :type patternWasFound: int - - - -The function draws the individual chessboard corners detected as red circles if the board was not found or as colored corners connected with lines if the board was found. - - -.. index:: FindChessboardCorners - -.. _FindChessboardCorners: - -FindChessboardCorners ---------------------- - - - - -.. function:: FindChessboardCorners(image, patternSize, flags=CV_CALIB_CB_ADAPTIVE_THRESH) -> corners - - Finds the positions of the internal corners of the chessboard. - - - - - - - :param image: Source chessboard view; it must be an 8-bit grayscale or color image - - :type image: :class:`CvArr` - - - :param patternSize: The number of inner corners per chessboard row and column - ( patternSize = cvSize(points _ per _ row,points _ per _ colum) = cvSize(columns,rows) ) - - :type patternSize: :class:`CvSize` - - - :param corners: The output array of corners detected - - :type corners: sequence of (float, float) - - - :param flags: Various operation flags, can be 0 or a combination of the following values: - - - * **CV_CALIB_CB_ADAPTIVE_THRESH** use adaptive thresholding to convert the image to black and white, rather than a fixed threshold level (computed from the average image brightness). - - - * **CV_CALIB_CB_NORMALIZE_IMAGE** normalize the image gamma with :ref:`EqualizeHist` before applying fixed or adaptive thresholding. - - - * **CV_CALIB_CB_FILTER_QUADS** use additional criteria (like contour area, perimeter, square-like shape) to filter out false quads that are extracted at the contour retrieval stage. - - - * **CALIB_CB_FAST_CHECK** Runs a fast check on the image that looks for chessboard corners, and shortcuts the call if none are found. This can drastically speed up the call in the degenerate condition when - no chessboard is observed. - - - - :type flags: int - - - -The function attempts to determine -whether the input image is a view of the chessboard pattern and -locate the internal chessboard corners. The function returns a non-zero -value if all of the corners have been found and they have been placed -in a certain order (row by row, left to right in every row), -otherwise, if the function fails to find all the corners or reorder -them, it returns 0. For example, a regular chessboard has 8 x 8 -squares and 7 x 7 internal corners, that is, points, where the black -squares touch each other. The coordinates detected are approximate, -and to determine their position more accurately, the user may use -the function -:ref:`FindCornerSubPix` -. - -Sample usage of detecting and drawing chessboard corners: - - - -:: - - - - Size patternsize(8,6); //interior number of corners - Mat gray = ....; //source image - vector corners; //this will be filled by the detected corners - - //CALIB_CB_FAST_CHECK saves a lot of time on images - //that don't contain any chessboard corners - bool patternfound = findChessboardCorners(gray, patternsize, corners, - CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE - + CALIB_CB_FAST_CHECK); - - if(patternfound) - cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1), - TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1)); - - drawChessboardCorners(img, patternsize, Mat(corners), patternfound); - - -.. - -**Note:** -the function requires some white space (like a square-thick border, the wider the better) around the board to make the detection more robust in various environment (otherwise if there is no border and the background is dark, the outer black squares could not be segmented properly and so the square grouping and ordering algorithm will fail). - - -.. index:: FindExtrinsicCameraParams2 - -.. _FindExtrinsicCameraParams2: - -FindExtrinsicCameraParams2 --------------------------- - - - - -.. function:: FindExtrinsicCameraParams2(objectPoints,imagePoints,cameraMatrix,distCoeffs,rvec,tvec,useExtrinsicGuess=0)-> None - - Finds the object pose from the 3D-2D point correspondences - - - - - - - :param objectPoints: The array of object points in the object coordinate space, 3xN or Nx3 1-channel, or 1xN or Nx1 3-channel, where N is the number of points. - - :type objectPoints: :class:`CvMat` - - - :param imagePoints: The array of corresponding image points, 2xN or Nx2 1-channel or 1xN or Nx1 2-channel, where N is the number of points. - - :type imagePoints: :class:`CvMat` - - - :param cameraMatrix: The input camera matrix :math:`A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}` - - :type cameraMatrix: :class:`CvMat` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - :type distCoeffs: :class:`CvMat` - - - :param rvec: The output rotation vector (see :ref:`Rodrigues2` ) that (together with ``tvec`` ) brings points from the model coordinate system to the camera coordinate system - - :type rvec: :class:`CvMat` - - - :param tvec: The output translation vector - - :type tvec: :class:`CvMat` - - - :param useExtrinsicGuess: If true (1), the function will use the provided ``rvec`` and ``tvec`` as the initial approximations of the rotation and translation vectors, respectively, and will further optimize them. - - :type useExtrinsicGuess: int - - - -The function estimates the object pose given a set of object points, their corresponding image projections, as well as the camera matrix and the distortion coefficients. This function finds such a pose that minimizes reprojection error, i.e. the sum of squared distances between the observed projections -``imagePoints`` -and the projected (using -:ref:`ProjectPoints2` -) -``objectPoints`` -. - - -The function's counterpart in the C++ API is - -.. index:: FindFundamentalMat - -.. _FindFundamentalMat: - -FindFundamentalMat ------------------- - - - - -.. function:: FindFundamentalMat(points1, points2, fundamentalMatrix, method=CV_FM_RANSAC, param1=1., param2=0.99, status = None) -> None - - Calculates the fundamental matrix from the corresponding points in two images. - - - - - - - :param points1: Array of ``N`` points from the first image. It can be ``2xN, Nx2, 3xN`` or ``Nx3`` 1-channel array or ``1xN`` or ``Nx1`` 2- or 3-channel array . The point coordinates should be floating-point (single or double precision) - - :type points1: :class:`CvMat` - - - :param points2: Array of the second image points of the same size and format as ``points1`` - - :type points2: :class:`CvMat` - - - :param fundamentalMatrix: The output fundamental matrix or matrices. The size should be 3x3 or 9x3 (7-point method may return up to 3 matrices) - - :type fundamentalMatrix: :class:`CvMat` - - - :param method: Method for computing the fundamental matrix - - - * **CV_FM_7POINT** for a 7-point algorithm. :math:`N = 7` - - - * **CV_FM_8POINT** for an 8-point algorithm. :math:`N \ge 8` - - - * **CV_FM_RANSAC** for the RANSAC algorithm. :math:`N \ge 8` - - - * **CV_FM_LMEDS** for the LMedS algorithm. :math:`N \ge 8` - - - - :type method: int - - - :param param1: The parameter is used for RANSAC. It is the maximum distance from point to epipolar line in pixels, beyond which the point is considered an outlier and is not used for computing the final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the point localization, image resolution and the image noise - - :type param1: float - - - :param param2: The parameter is used for RANSAC or LMedS methods only. It specifies the desirable level of confidence (probability) that the estimated matrix is correct - - :type param2: float - - - :param status: The optional output array of N elements, every element of which is set to 0 for outliers and to 1 for the other points. The array is computed only in RANSAC and LMedS methods. For other methods it is set to all 1's - - :type status: :class:`CvMat` - - - -The epipolar geometry is described by the following equation: - - - -.. math:: - - [p_2; 1]^T F [p_1; 1] = 0 - - -where -:math:`F` -is fundamental matrix, -:math:`p_1` -and -:math:`p_2` -are corresponding points in the first and the second images, respectively. - -The function calculates the fundamental matrix using one of four methods listed above and returns -the number of fundamental matrices found (1 or 3) and 0, if no matrix is found -. Normally just 1 matrix is found, but in the case of 7-point algorithm the function may return up to 3 solutions ( -:math:`9 \times 3` -matrix that stores all 3 matrices sequentially). - -The calculated fundamental matrix may be passed further to -:ref:`ComputeCorrespondEpilines` -that finds the epipolar lines -corresponding to the specified points. It can also be passed to -:ref:`StereoRectifyUncalibrated` -to compute the rectification transformation. - - -.. index:: FindHomography - -.. _FindHomography: - -FindHomography --------------- - - - - -.. function:: FindHomography(srcPoints,dstPoints,H,method,ransacReprojThreshold=3.0, status=None)-> None - - Finds the perspective transformation between two planes. - - - - - - - :param srcPoints: Coordinates of the points in the original plane, 2xN, Nx2, 3xN or Nx3 1-channel array (the latter two are for representation in homogeneous coordinates), where N is the number of points. 1xN or Nx1 2- or 3-channel array can also be passed. - - :type srcPoints: :class:`CvMat` - - :param dstPoints: Point coordinates in the destination plane, 2xN, Nx2, 3xN or Nx3 1-channel, or 1xN or Nx1 2- or 3-channel array. - - :type dstPoints: :class:`CvMat` - - - :param H: The output 3x3 homography matrix - - :type H: :class:`CvMat` - - - :param method: The method used to computed homography matrix; one of the following: - - * **0** a regular method using all the points - - * **CV_RANSAC** RANSAC-based robust method - - * **CV_LMEDS** Least-Median robust method - - - - :type method: int - - - :param ransacReprojThreshold: The maximum allowed reprojection error to treat a point pair as an inlier (used in the RANSAC method only). That is, if - - .. math:: - - \| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} \texttt{srcPoints} _i) \| > \texttt{ransacReprojThreshold} - - then the point :math:`i` is considered an outlier. If ``srcPoints`` and ``dstPoints`` are measured in pixels, it usually makes sense to set this parameter somewhere in the range 1 to 10. - - :type ransacReprojThreshold: float - - - :param status: The optional output mask set by a robust method ( ``CV_RANSAC`` or ``CV_LMEDS`` ). *Note that the input mask values are ignored.* - - :type status: :class:`CvMat` - - - -The -function finds -the perspective transformation -:math:`H` -between the source and the destination planes: - - - -.. math:: - - s_i \vecthree{x'_i}{y'_i}{1} \sim H \vecthree{x_i}{y_i}{1} - - -So that the back-projection error - - - -.. math:: - - \sum _i \left ( x'_i- \frac{h_{11} x_i + h_{12} y_i + h_{13}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2+ \left ( y'_i- \frac{h_{21} x_i + h_{22} y_i + h_{23}}{h_{31} x_i + h_{32} y_i + h_{33}} \right )^2 - - -is minimized. If the parameter -``method`` -is set to the default value 0, the function -uses all the point pairs to compute the initial homography estimate with a simple least-squares scheme. - -However, if not all of the point pairs ( -:math:`srcPoints_i` -, -:math:`dstPoints_i` -) fit the rigid perspective transformation (i.e. there -are some outliers), this initial estimate will be poor. -In this case one can use one of the 2 robust methods. Both methods, -``RANSAC`` -and -``LMeDS`` -, try many different random subsets -of the corresponding point pairs (of 4 pairs each), estimate -the homography matrix using this subset and a simple least-square -algorithm and then compute the quality/goodness of the computed homography -(which is the number of inliers for RANSAC or the median re-projection -error for LMeDs). The best subset is then used to produce the initial -estimate of the homography matrix and the mask of inliers/outliers. - -Regardless of the method, robust or not, the computed homography -matrix is refined further (using inliers only in the case of a robust -method) with the Levenberg-Marquardt method in order to reduce the -re-projection error even more. - -The method -``RANSAC`` -can handle practically any ratio of outliers, -but it needs the threshold to distinguish inliers from outliers. -The method -``LMeDS`` -does not need any threshold, but it works -correctly only when there are more than 50 -% -of inliers. Finally, -if you are sure in the computed features, where can be only some -small noise present, but no outliers, the default method could be the best -choice. - -The function is used to find initial intrinsic and extrinsic matrices. -Homography matrix is determined up to a scale, thus it is normalized so that -:math:`h_{33}=1` -. - -See also: -:ref:`GetAffineTransform` -, -:ref:`GetPerspectiveTransform` -, -:ref:`EstimateRigidMotion` -, -:ref:`WarpPerspective` -, -:ref:`PerspectiveTransform` - -.. index:: FindStereoCorrespondenceBM - -.. _FindStereoCorrespondenceBM: - -FindStereoCorrespondenceBM --------------------------- - - - - -.. function:: FindStereoCorrespondenceBM(left,right,disparity,state)-> None - - Computes the disparity map using block matching algorithm. - - - - - - - :param left: The left single-channel, 8-bit image. - - :type left: :class:`CvArr` - - - :param right: The right image of the same size and the same type. - - :type right: :class:`CvArr` - - - :param disparity: The output single-channel 16-bit signed, or 32-bit floating-point disparity map of the same size as input images. In the first case the computed disparities are represented as fixed-point numbers with 4 fractional bits (i.e. the computed disparity values are multiplied by 16 and rounded to integers). - - :type disparity: :class:`CvArr` - - - :param state: Stereo correspondence structure. - - :type state: :class:`CvStereoBMState` - - - -The function cvFindStereoCorrespondenceBM computes disparity map for the input rectified stereo pair. Invalid pixels (for which disparity can not be computed) are set to -``state->minDisparity - 1`` -(or to -``(state->minDisparity-1)*16`` -in the case of 16-bit fixed-point disparity map) - - -.. index:: FindStereoCorrespondenceGC - -.. _FindStereoCorrespondenceGC: - -FindStereoCorrespondenceGC --------------------------- - - - - -.. function:: FindStereoCorrespondenceGC( left, right, dispLeft, dispRight, state, useDisparityGuess=(0))-> None - - Computes the disparity map using graph cut-based algorithm. - - - - - - - :param left: The left single-channel, 8-bit image. - - :type left: :class:`CvArr` - - - :param right: The right image of the same size and the same type. - - :type right: :class:`CvArr` - - - :param dispLeft: The optional output single-channel 16-bit signed left disparity map of the same size as input images. - - :type dispLeft: :class:`CvArr` - - - :param dispRight: The optional output single-channel 16-bit signed right disparity map of the same size as input images. - - :type dispRight: :class:`CvArr` - - - :param state: Stereo correspondence structure. - - :type state: :class:`CvStereoGCState` - - - :param useDisparityGuess: If the parameter is not zero, the algorithm will start with pre-defined disparity maps. Both dispLeft and dispRight should be valid disparity maps. Otherwise, the function starts with blank disparity maps (all pixels are marked as occlusions). - - :type useDisparityGuess: int - - - -The function computes disparity maps for the input rectified stereo pair. Note that the left disparity image will contain values in the following range: - - - -.. math:: - - - \texttt{state->numberOfDisparities} - \texttt{state->minDisparity} < dispLeft(x,y) \le - \texttt{state->minDisparity} , - - -or - - -.. math:: - - dispLeft(x,y) == \texttt{CV\_STEREO\_GC\_OCCLUSION} - - -and for the right disparity image the following will be true: - - - -.. math:: - - \texttt{state->minDisparity} \le dispRight(x,y) - < \texttt{state->minDisparity} + \texttt{state->numberOfDisparities} - - -or - - - -.. math:: - - dispRight(x,y) == \texttt{CV\_STEREO\_GC\_OCCLUSION} - - -that is, the range for the left disparity image will be inversed, -and the pixels for which no good match has been found, will be marked -as occlusions. - -Here is how the function can be used: - -.. include:: ../../python_fragments/findstereocorrespondence.py - :literal: - - -and this is the output left disparity image computed from the well-known -Tsukuba stereo pair and multiplied by -16 (because the values in the -left disparity images are usually negative): - - - -.. image:: ../pics/disparity.png - - - - -.. index:: GetOptimalNewCameraMatrix - -.. _GetOptimalNewCameraMatrix: - -GetOptimalNewCameraMatrix -------------------------- - - - - -.. function:: GetOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, alpha, newCameraMatrix, newImageSize=(0,0), validPixROI=0) -> None - - Returns the new camera matrix based on the free scaling parameter - - - - - - - :param cameraMatrix: The input camera matrix - - :type cameraMatrix: :class:`CvMat` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - :type distCoeffs: :class:`CvMat` - - - :param imageSize: The original image size - - :type imageSize: :class:`CvSize` - - - :param alpha: The free scaling parameter between 0 (when all the pixels in the undistorted image will be valid) and 1 (when all the source image pixels will be retained in the undistorted image); see :ref:`StereoRectify` - - :type alpha: float - - - :param newCameraMatrix: The output new camera matrix. - - :type newCameraMatrix: :class:`CvMat` - - - :param newImageSize: The image size after rectification. By default it will be set to ``imageSize`` . - - :type newImageSize: :class:`CvSize` - - - :param validPixROI: The optional output rectangle that will outline all-good-pixels region in the undistorted image. See ``roi1, roi2`` description in :ref:`StereoRectify` - - :type validPixROI: :class:`CvRect` - - - -The function computes -the optimal new camera matrix based on the free scaling parameter. By varying this parameter the user may retrieve only sensible pixels -``alpha=0`` -, keep all the original image pixels if there is valuable information in the corners -``alpha=1`` -, or get something in between. When -``alpha>0`` -, the undistortion result will likely have some black pixels corresponding to "virtual" pixels outside of the captured distorted image. The original camera matrix, distortion coefficients, the computed new camera matrix and the -``newImageSize`` -should be passed to -:ref:`InitUndistortRectifyMap` -to produce the maps for -:ref:`Remap` -. - - -.. index:: InitIntrinsicParams2D - -.. _InitIntrinsicParams2D: - -InitIntrinsicParams2D ---------------------- - - - - -.. function:: InitIntrinsicParams2D(objectPoints, imagePoints, npoints, imageSize, cameraMatrix, aspectRatio=1.) -> None - - Finds the initial camera matrix from the 3D-2D point correspondences - - - - - - - :param objectPoints: The joint array of object points; see :ref:`CalibrateCamera2` - - :type objectPoints: :class:`CvMat` - - - :param imagePoints: The joint array of object point projections; see :ref:`CalibrateCamera2` - - :type imagePoints: :class:`CvMat` - - - :param npoints: The array of point counts; see :ref:`CalibrateCamera2` - - :type npoints: :class:`CvMat` - - - :param imageSize: The image size in pixels; used to initialize the principal point - - :type imageSize: :class:`CvSize` - - - :param cameraMatrix: The output camera matrix :math:`\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` - - :type cameraMatrix: :class:`CvMat` - - - :param aspectRatio: If it is zero or negative, both :math:`f_x` and :math:`f_y` are estimated independently. Otherwise :math:`f_x = f_y * \texttt{aspectRatio}` - - :type aspectRatio: float - - - -The function estimates and returns the initial camera matrix for camera calibration process. -Currently, the function only supports planar calibration patterns, i.e. patterns where each object point has z-coordinate =0. - - -.. index:: InitUndistortMap - -.. _InitUndistortMap: - -InitUndistortMap ----------------- - - - - -.. function:: InitUndistortMap(cameraMatrix,distCoeffs,map1,map2)-> None - - Computes an undistortion map. - - - - - - - :param cameraMatrix: The input camera matrix :math:`A = \vecthreethree{fx}{0}{cx}{0}{fy}{cy}{0}{0}{1}` - - :type cameraMatrix: :class:`CvMat` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - :type distCoeffs: :class:`CvMat` - - - :param map1: The first output map of type ``CV_32FC1`` or ``CV_16SC2`` - the second variant is more efficient - - :type map1: :class:`CvArr` - - - :param map2: The second output map of type ``CV_32FC1`` or ``CV_16UC1`` - the second variant is more efficient - - :type map2: :class:`CvArr` - - - -The function is a simplified variant of -:ref:`InitUndistortRectifyMap` -where the rectification transformation -``R`` -is identity matrix and -``newCameraMatrix=cameraMatrix`` -. - - -.. index:: InitUndistortRectifyMap - -.. _InitUndistortRectifyMap: - -InitUndistortRectifyMap ------------------------ - - - - -.. function:: InitUndistortRectifyMap(cameraMatrix,distCoeffs,R,newCameraMatrix,map1,map2)-> None - - Computes the undistortion and rectification transformation map. - - - - - - - :param cameraMatrix: The input camera matrix :math:`A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` - - :type cameraMatrix: :class:`CvMat` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - :type distCoeffs: :class:`CvMat` - - - :param R: The optional rectification transformation in object space (3x3 matrix). ``R1`` or ``R2`` , computed by :ref:`StereoRectify` can be passed here. If the matrix is NULL , the identity transformation is assumed - - :type R: :class:`CvMat` - - - :param newCameraMatrix: The new camera matrix :math:`A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}` - - :type newCameraMatrix: :class:`CvMat` - - - :param map1: The first output map of type ``CV_32FC1`` or ``CV_16SC2`` - the second variant is more efficient - - :type map1: :class:`CvArr` - - - :param map2: The second output map of type ``CV_32FC1`` or ``CV_16UC1`` - the second variant is more efficient - - :type map2: :class:`CvArr` - - - -The function computes the joint undistortion+rectification transformation and represents the result in the form of maps for -:ref:`Remap` -. The undistorted image will look like the original, as if it was captured with a camera with camera matrix -``=newCameraMatrix`` -and zero distortion. In the case of monocular camera -``newCameraMatrix`` -is usually equal to -``cameraMatrix`` -, or it can be computed by -:ref:`GetOptimalNewCameraMatrix` -for a better control over scaling. In the case of stereo camera -``newCameraMatrix`` -is normally set to -``P1`` -or -``P2`` -computed by -:ref:`StereoRectify` -. - -Also, this new camera will be oriented differently in the coordinate space, according to -``R`` -. That, for example, helps to align two heads of a stereo camera so that the epipolar lines on both images become horizontal and have the same y- coordinate (in the case of horizontally aligned stereo camera). - -The function actually builds the maps for the inverse mapping algorithm that is used by -:ref:`Remap` -. That is, for each pixel -:math:`(u, v)` -in the destination (corrected and rectified) image the function computes the corresponding coordinates in the source image (i.e. in the original image from camera). The process is the following: - - - -.. math:: - - \begin{array}{l} x \leftarrow (u - {c'}_x)/{f'}_x \\ y \leftarrow (v - {c'}_y)/{f'}_y \\{[X\,Y\,W]} ^T \leftarrow R^{-1}*[x \, y \, 1]^T \\ x' \leftarrow X/W \\ y' \leftarrow Y/W \\ x" \leftarrow x' (1 + k_1 r^2 + k_2 r^4 + k_3 r^6) + 2p_1 x' y' + p_2(r^2 + 2 x'^2) \\ y" \leftarrow y' (1 + k_1 r^2 + k_2 r^4 + k_3 r^6) + p_1 (r^2 + 2 y'^2) + 2 p_2 x' y' \\ map_x(u,v) \leftarrow x" f_x + c_x \\ map_y(u,v) \leftarrow y" f_y + c_y \end{array} - - -where -:math:`(k_1, k_2, p_1, p_2[, k_3])` -are the distortion coefficients. - -In the case of a stereo camera this function is called twice, once for each camera head, after -:ref:`StereoRectify` -, which in its turn is called after -:ref:`StereoCalibrate` -. But if the stereo camera was not calibrated, it is still possible to compute the rectification transformations directly from the fundamental matrix using -:ref:`StereoRectifyUncalibrated` -. For each camera the function computes homography -``H`` -as the rectification transformation in pixel domain, not a rotation matrix -``R`` -in 3D space. The -``R`` -can be computed from -``H`` -as - - - -.. math:: - - \texttt{R} = \texttt{cameraMatrix} ^{-1} \cdot \texttt{H} \cdot \texttt{cameraMatrix} - - -where the -``cameraMatrix`` -can be chosen arbitrarily. - - -.. index:: POSIT - -.. _POSIT: - -POSIT ------ - - - - -.. function:: POSIT(posit_object,imagePoints,focal_length,criteria)-> (rotationMatrix,translation_vector) - - Implements the POSIT algorithm. - - - - - - - :param posit_object: Pointer to the object structure - - :type posit_object: :class:`CvPOSITObject` - - - :param imagePoints: Pointer to the object points projections on the 2D image plane - - :type imagePoints: :class:`CvPoint2D32f` - - - :param focal_length: Focal length of the camera used - - :type focal_length: float - - - :param criteria: Termination criteria of the iterative POSIT algorithm - - :type criteria: :class:`CvTermCriteria` - - - :param rotationMatrix: Matrix of rotations - - :type rotationMatrix: :class:`CvMatr32f_i` - - - :param translation_vector: Translation vector - - :type translation_vector: :class:`CvVect32f_i` - - - -The function implements the POSIT algorithm. Image coordinates are given in a camera-related coordinate system. The focal length may be retrieved using the camera calibration functions. At every iteration of the algorithm a new perspective projection of the estimated pose is computed. - -Difference norm between two projections is the maximal distance between corresponding points. The parameter -``criteria.epsilon`` -serves to stop the algorithm if the difference is small. - - -.. index:: ProjectPoints2 - -.. _ProjectPoints2: - -ProjectPoints2 --------------- - - - - -.. function:: ProjectPoints2(objectPoints,rvec,tvec,cameraMatrix,distCoeffs, imagePoints,dpdrot=NULL,dpdt=NULL,dpdf=NULL,dpdc=NULL,dpddist=NULL)-> None - - Project 3D points on to an image plane. - - - - - - - :param objectPoints: The array of object points, 3xN or Nx3 1-channel or 1xN or Nx1 3-channel , where N is the number of points in the view - - :type objectPoints: :class:`CvMat` - - - :param rvec: The rotation vector, see :ref:`Rodrigues2` - - :type rvec: :class:`CvMat` - - - :param tvec: The translation vector - - :type tvec: :class:`CvMat` - - - :param cameraMatrix: The camera matrix :math:`A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}` - - :type cameraMatrix: :class:`CvMat` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - :type distCoeffs: :class:`CvMat` - - - :param imagePoints: The output array of image points, 2xN or Nx2 1-channel or 1xN or Nx1 2-channel - - :type imagePoints: :class:`CvMat` - - - :param dpdrot: Optional 2Nx3 matrix of derivatives of image points with respect to components of the rotation vector - - :type dpdrot: :class:`CvMat` - - - :param dpdt: Optional 2Nx3 matrix of derivatives of image points with respect to components of the translation vector - - :type dpdt: :class:`CvMat` - - - :param dpdf: Optional 2Nx2 matrix of derivatives of image points with respect to :math:`f_x` and :math:`f_y` - - :type dpdf: :class:`CvMat` - - - :param dpdc: Optional 2Nx2 matrix of derivatives of image points with respect to :math:`c_x` and :math:`c_y` - - :type dpdc: :class:`CvMat` - - - :param dpddist: Optional 2Nx4 matrix of derivatives of image points with respect to distortion coefficients - - :type dpddist: :class:`CvMat` - - - -The function computes projections of 3D -points to the image plane given intrinsic and extrinsic camera -parameters. Optionally, the function computes jacobians - matrices -of partial derivatives of image points coordinates (as functions of all the -input parameters) with respect to the particular parameters, intrinsic and/or -extrinsic. The jacobians are used during the global optimization -in -:ref:`CalibrateCamera2` -, -:ref:`FindExtrinsicCameraParams2` -and -:ref:`StereoCalibrate` -. The -function itself can also used to compute re-projection error given the -current intrinsic and extrinsic parameters. - -Note, that by setting -``rvec=tvec=(0,0,0)`` -, or by setting -``cameraMatrix`` -to 3x3 identity matrix, or by passing zero distortion coefficients, you can get various useful partial cases of the function, i.e. you can compute the distorted coordinates for a sparse set of points, or apply a perspective transformation (and also compute the derivatives) in the ideal zero-distortion setup etc. - - - -.. index:: ReprojectImageTo3D - -.. _ReprojectImageTo3D: - -ReprojectImageTo3D ------------------- - - - - -.. function:: ReprojectImageTo3D(disparity, _3dImage, Q, handleMissingValues=0) -> None - - Reprojects disparity image to 3D space. - - - - - - - :param disparity: The input single-channel 16-bit signed or 32-bit floating-point disparity image - - :type disparity: :class:`CvArr` - - - :param _3dImage: The output 3-channel floating-point image of the same size as ``disparity`` . - Each element of ``_3dImage(x,y)`` will contain the 3D coordinates of the point ``(x,y)`` , computed from the disparity map. - - :type _3dImage: :class:`CvArr` - - - :param Q: The :math:`4 \times 4` perspective transformation matrix that can be obtained with :ref:`StereoRectify` - - :type Q: :class:`CvMat` - - - :param handleMissingValues: If true, when the pixels with the minimal disparity (that corresponds to the outliers; see :ref:`FindStereoCorrespondenceBM` ) will be transformed to 3D points with some very large Z value (currently set to 10000) - - :type handleMissingValues: int - - - -The function transforms 1-channel disparity map to 3-channel image representing a 3D surface. That is, for each pixel -``(x,y)`` -and the corresponding disparity -``d=disparity(x,y)`` -it computes: - - - -.. math:: - - \begin{array}{l} [X \; Y \; Z \; W]^T = \texttt{Q} *[x \; y \; \texttt{disparity} (x,y) \; 1]^T \\ \texttt{\_3dImage} (x,y) = (X/W, \; Y/W, \; Z/W) \end{array} - - -The matrix -``Q`` -can be arbitrary -:math:`4 \times 4` -matrix, e.g. the one computed by -:ref:`StereoRectify` -. To reproject a sparse set of points {(x,y,d),...} to 3D space, use -:ref:`PerspectiveTransform` -. - - -.. index:: RQDecomp3x3 - -.. _RQDecomp3x3: - -RQDecomp3x3 ------------ - - - - -.. function:: RQDecomp3x3(M, R, Q, Qx = None, Qy = None, Qz = None) -> eulerAngles - - Computes the 'RQ' decomposition of 3x3 matrices. - - - - - - - :param M: The 3x3 input matrix - - :type M: :class:`CvMat` - - - :param R: The output 3x3 upper-triangular matrix - - :type R: :class:`CvMat` - - - :param Q: The output 3x3 orthogonal matrix - - :type Q: :class:`CvMat` - - - :param Qx: Optional 3x3 rotation matrix around x-axis - - :type Qx: :class:`CvMat` - - - :param Qy: Optional 3x3 rotation matrix around y-axis - - :type Qy: :class:`CvMat` - - - :param Qz: Optional 3x3 rotation matrix around z-axis - - :type Qz: :class:`CvMat` - - - :param eulerAngles: Optional three Euler angles of rotation - - :type eulerAngles: :class:`CvPoint3D64f` - - - -The function computes a RQ decomposition using the given rotations. This function is used in -:ref:`DecomposeProjectionMatrix` -to decompose the left 3x3 submatrix of a projection matrix into a camera and a rotation matrix. - -It optionally returns three rotation matrices, one for each axis, and the three Euler angles -that could be used in OpenGL. - - -.. index:: Rodrigues2 - -.. _Rodrigues2: - -Rodrigues2 ----------- - - - - -.. function:: Rodrigues2(src,dst,jacobian=0)-> None - - Converts a rotation matrix to a rotation vector or vice versa. - - - - - - - :param src: The input rotation vector (3x1 or 1x3) or rotation matrix (3x3) - - :type src: :class:`CvMat` - - - :param dst: The output rotation matrix (3x3) or rotation vector (3x1 or 1x3), respectively - - :type dst: :class:`CvMat` - - - :param jacobian: Optional output Jacobian matrix, 3x9 or 9x3 - partial derivatives of the output array components with respect to the input array components - - :type jacobian: :class:`CvMat` - - - - - -.. math:: - - \begin{array}{l} \theta \leftarrow norm(r) \\ r \leftarrow r/ \theta \\ R = \cos{\theta} I + (1- \cos{\theta} ) r r^T + \sin{\theta} \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} \end{array} - - -Inverse transformation can also be done easily, since - - - -.. math:: - - \sin ( \theta ) \vecthreethree{0}{-r_z}{r_y}{r_z}{0}{-r_x}{-r_y}{r_x}{0} = \frac{R - R^T}{2} - - -A rotation vector is a convenient and most-compact representation of a rotation matrix -(since any rotation matrix has just 3 degrees of freedom). The representation is -used in the global 3D geometry optimization procedures like -:ref:`CalibrateCamera2` -, -:ref:`StereoCalibrate` -or -:ref:`FindExtrinsicCameraParams2` -. - - - -.. index:: StereoCalibrate - -.. _StereoCalibrate: - -StereoCalibrate ---------------- - - - - -.. function:: StereoCalibrate( objectPoints, imagePoints1, imagePoints2, pointCounts, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T, E=NULL, F=NULL, term_crit=(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,30,1e-6), flags=CV_CALIB_FIX_INTRINSIC)-> None - - Calibrates stereo camera. - - - - - - - :param objectPoints: The joint matrix of object points - calibration pattern features in the model coordinate space. It is floating-point 3xN or Nx3 1-channel, or 1xN or Nx1 3-channel array, where N is the total number of points in all views. - - :type objectPoints: :class:`CvMat` - - - :param imagePoints1: The joint matrix of object points projections in the first camera views. It is floating-point 2xN or Nx2 1-channel, or 1xN or Nx1 2-channel array, where N is the total number of points in all views - - :type imagePoints1: :class:`CvMat` - - - :param imagePoints2: The joint matrix of object points projections in the second camera views. It is floating-point 2xN or Nx2 1-channel, or 1xN or Nx1 2-channel array, where N is the total number of points in all views - - :type imagePoints2: :class:`CvMat` - - - :param pointCounts: Integer 1xM or Mx1 vector (where M is the number of calibration pattern views) containing the number of points in each particular view. The sum of vector elements must match the size of ``objectPoints`` and ``imagePoints*`` (=N). - - :type pointCounts: :class:`CvMat` - - - :param cameraMatrix1: The input/output first camera matrix: :math:`\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}` , :math:`j = 0,\, 1` . If any of ``CV_CALIB_USE_INTRINSIC_GUESS`` , ``CV_CALIB_FIX_ASPECT_RATIO`` , ``CV_CALIB_FIX_INTRINSIC`` or ``CV_CALIB_FIX_FOCAL_LENGTH`` are specified, some or all of the matrices' components must be initialized; see the flags description - - :type cameraMatrix1: :class:`CvMat` - - - :param distCoeffs: The input/output vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. - - - :param cameraMatrix2: The input/output second camera matrix, as cameraMatrix1. - - :type cameraMatrix2: :class:`CvMat` - - - :param distCoeffs2: The input/output lens distortion coefficients for the second camera, as ``distCoeffs1`` . - - :type distCoeffs2: :class:`CvMat` - - - :param imageSize: Size of the image, used only to initialize intrinsic camera matrix. - - :type imageSize: :class:`CvSize` - - - :param R: The output rotation matrix between the 1st and the 2nd cameras' coordinate systems. - - :type R: :class:`CvMat` - - - :param T: The output translation vector between the cameras' coordinate systems. - - :type T: :class:`CvMat` - - - :param E: The optional output essential matrix. - - :type E: :class:`CvMat` - - - :param F: The optional output fundamental matrix. - - :type F: :class:`CvMat` - - - :param term_crit: The termination criteria for the iterative optimization algorithm. - - :type term_crit: :class:`CvTermCriteria` - - - :param flags: Different flags, may be 0 or combination of the following values: - - * **CV_CALIB_FIX_INTRINSIC** If it is set, ``cameraMatrix?`` , as well as ``distCoeffs?`` are fixed, so that only ``R, T, E`` and ``F`` are estimated. - - * **CV_CALIB_USE_INTRINSIC_GUESS** The flag allows the function to optimize some or all of the intrinsic parameters, depending on the other flags, but the initial values are provided by the user. - - * **CV_CALIB_FIX_PRINCIPAL_POINT** The principal points are fixed during the optimization. - - * **CV_CALIB_FIX_FOCAL_LENGTH** :math:`f^{(j)}_x` and :math:`f^{(j)}_y` are fixed. - - * **CV_CALIB_FIX_ASPECT_RATIO** :math:`f^{(j)}_y` is optimized, but the ratio :math:`f^{(j)}_x/f^{(j)}_y` is fixed. - - * **CV_CALIB_SAME_FOCAL_LENGTH** Enforces :math:`f^{(0)}_x=f^{(1)}_x` and :math:`f^{(0)}_y=f^{(1)}_y` - - * **CV_CALIB_ZERO_TANGENT_DIST** Tangential distortion coefficients for each camera are set to zeros and fixed there. - - * **CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6** Do not change the corresponding radial distortion coefficient during the optimization. If ``CV_CALIB_USE_INTRINSIC_GUESS`` is set, the coefficient from the supplied ``distCoeffs`` matrix is used, otherwise it is set to 0. - - * **CV_CALIB_RATIONAL_MODEL** Enable coefficients k4, k5 and k6. To provide the backward compatibility, this extra flag should be explicitly specified to make the calibration function use the rational model and return 8 coefficients. If the flag is not set, the function will compute only 5 distortion coefficients. - - - - :type flags: int - - - -The function estimates transformation between the 2 cameras making a stereo pair. If we have a stereo camera, where the relative position and orientation of the 2 cameras is fixed, and if we computed poses of an object relative to the fist camera and to the second camera, (R1, T1) and (R2, T2), respectively (that can be done with -:ref:`FindExtrinsicCameraParams2` -), obviously, those poses will relate to each other, i.e. given ( -:math:`R_1` -, -:math:`T_1` -) it should be possible to compute ( -:math:`R_2` -, -:math:`T_2` -) - we only need to know the position and orientation of the 2nd camera relative to the 1st camera. That's what the described function does. It computes ( -:math:`R` -, -:math:`T` -) such that: - - - -.. math:: - - R_2=R*R_1 - T_2=R*T_1 + T, - - -Optionally, it computes the essential matrix E: - - - -.. math:: - - E= \vecthreethree{0}{-T_2}{T_1}{T_2}{0}{-T_0}{-T_1}{T_0}{0} *R - - -where -:math:`T_i` -are components of the translation vector -:math:`T` -: -:math:`T=[T_0, T_1, T_2]^T` -. And also the function can compute the fundamental matrix F: - - - -.. math:: - - F = cameraMatrix2^{-T} E cameraMatrix1^{-1} - - -Besides the stereo-related information, the function can also perform full calibration of each of the 2 cameras. However, because of the high dimensionality of the parameter space and noise in the input data the function can diverge from the correct solution. Thus, if intrinsic parameters can be estimated with high accuracy for each of the cameras individually (e.g. using -:ref:`CalibrateCamera2` -), it is recommended to do so and then pass -``CV_CALIB_FIX_INTRINSIC`` -flag to the function along with the computed intrinsic parameters. Otherwise, if all the parameters are estimated at once, it makes sense to restrict some parameters, e.g. pass -``CV_CALIB_SAME_FOCAL_LENGTH`` -and -``CV_CALIB_ZERO_TANGENT_DIST`` -flags, which are usually reasonable assumptions. - -Similarly to -:ref:`CalibrateCamera2` -, the function minimizes the total re-projection error for all the points in all the available views from both cameras. - -.. index:: StereoRectify - -.. _StereoRectify: - -StereoRectify -------------- - - - - -.. function:: StereoRectify( cameraMatrix1, cameraMatrix2, distCoeffs1, distCoeffs2, imageSize, R, T, R1, R2, P1, P2, Q=NULL, flags=CV_CALIB_ZERO_DISPARITY, alpha=-1, newImageSize=(0,0))-> (roi1, roi2) - - Computes rectification transforms for each head of a calibrated stereo camera. - - - - - - - :param cameraMatrix1, cameraMatrix2: The camera matrices :math:`\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}` . - - - :param distCoeffs: The input vectors of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements each. If the vectors are NULL/empty, the zero distortion coefficients are assumed. - - - :param imageSize: Size of the image used for stereo calibration. - - :type imageSize: :class:`CvSize` - - - :param R: The rotation matrix between the 1st and the 2nd cameras' coordinate systems. - - :type R: :class:`CvMat` - - - :param T: The translation vector between the cameras' coordinate systems. - - :type T: :class:`CvMat` - - - :param R1, R2: The output :math:`3 \times 3` rectification transforms (rotation matrices) for the first and the second cameras, respectively. - - - :param P1, P2: The output :math:`3 \times 4` projection matrices in the new (rectified) coordinate systems. - - - :param Q: The output :math:`4 \times 4` disparity-to-depth mapping matrix, see :cpp:func:`reprojectImageTo3D` . - - :type Q: :class:`CvMat` - - - :param flags: The operation flags; may be 0 or ``CV_CALIB_ZERO_DISPARITY`` . If the flag is set, the function makes the principal points of each camera have the same pixel coordinates in the rectified views. And if the flag is not set, the function may still shift the images in horizontal or vertical direction (depending on the orientation of epipolar lines) in order to maximize the useful image area. - - :type flags: int - - - :param alpha: The free scaling parameter. If it is -1 , the functions performs some default scaling. Otherwise the parameter should be between 0 and 1. ``alpha=0`` means that the rectified images will be zoomed and shifted so that only valid pixels are visible (i.e. there will be no black areas after rectification). ``alpha=1`` means that the rectified image will be decimated and shifted so that all the pixels from the original images from the cameras are retained in the rectified images, i.e. no source image pixels are lost. Obviously, any intermediate value yields some intermediate result between those two extreme cases. - - :type alpha: float - - - :param newImageSize: The new image resolution after rectification. The same size should be passed to :ref:`InitUndistortRectifyMap` , see the ``stereo_calib.cpp`` sample in OpenCV samples directory. By default, i.e. when (0,0) is passed, it is set to the original ``imageSize`` . Setting it to larger value can help you to preserve details in the original image, especially when there is big radial distortion. - - :type newImageSize: :class:`CvSize` - - - :param roi1, roi2: The optional output rectangles inside the rectified images where all the pixels are valid. If ``alpha=0`` , the ROIs will cover the whole images, otherwise they likely be smaller, see the picture below - - - -The function computes the rotation matrices for each camera that (virtually) make both camera image planes the same plane. Consequently, that makes all the epipolar lines parallel and thus simplifies the dense stereo correspondence problem. On input the function takes the matrices computed by -:cpp:func:`stereoCalibrate` -and on output it gives 2 rotation matrices and also 2 projection matrices in the new coordinates. The 2 cases are distinguished by the function are: - - - - - -#. - Horizontal stereo, when 1st and 2nd camera views are shifted relative to each other mainly along the x axis (with possible small vertical shift). Then in the rectified images the corresponding epipolar lines in left and right cameras will be horizontal and have the same y-coordinate. P1 and P2 will look as: - - - - .. math:: - - \texttt{P1} = \begin{bmatrix} f & 0 & cx_1 & 0 \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} - - - - - .. math:: - - \texttt{P2} = \begin{bmatrix} f & 0 & cx_2 & T_x*f \\ 0 & f & cy & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} , - - - where - :math:`T_x` - is horizontal shift between the cameras and - :math:`cx_1=cx_2` - if - ``CV_CALIB_ZERO_DISPARITY`` - is set. - - -#. - Vertical stereo, when 1st and 2nd camera views are shifted relative to each other mainly in vertical direction (and probably a bit in the horizontal direction too). Then the epipolar lines in the rectified images will be vertical and have the same x coordinate. P2 and P2 will look as: - - - - .. math:: - - \texttt{P1} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_1 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} - - - - - .. math:: - - \texttt{P2} = \begin{bmatrix} f & 0 & cx & 0 \\ 0 & f & cy_2 & T_y*f \\ 0 & 0 & 1 & 0 \end{bmatrix} , - - - where - :math:`T_y` - is vertical shift between the cameras and - :math:`cy_1=cy_2` - if - ``CALIB_ZERO_DISPARITY`` - is set. - - -As you can see, the first 3 columns of -``P1`` -and -``P2`` -will effectively be the new "rectified" camera matrices. -The matrices, together with -``R1`` -and -``R2`` -, can then be passed to -:ref:`InitUndistortRectifyMap` -to initialize the rectification map for each camera. - -Below is the screenshot from -``stereo_calib.cpp`` -sample. Some red horizontal lines, as you can see, pass through the corresponding image regions, i.e. the images are well rectified (which is what most stereo correspondence algorithms rely on). The green rectangles are -``roi1`` -and -``roi2`` -- indeed, their interior are all valid pixels. - - - -.. image:: ../pics/stereo_undistort.jpg - - - - -.. index:: StereoRectifyUncalibrated - -.. _StereoRectifyUncalibrated: - -StereoRectifyUncalibrated -------------------------- - - - - -.. function:: StereoRectifyUncalibrated(points1,points2,F,imageSize,H1,H2,threshold=5)-> None - - Computes rectification transform for uncalibrated stereo camera. - - - - - - - :param points1, points2: The 2 arrays of corresponding 2D points. The same formats as in :ref:`FindFundamentalMat` are supported - - - :param F: The input fundamental matrix. It can be computed from the same set of point pairs using :ref:`FindFundamentalMat` . - - :type F: :class:`CvMat` - - - :param imageSize: Size of the image. - - :type imageSize: :class:`CvSize` - - - :param H1, H2: The output rectification homography matrices for the first and for the second images. - - - :param threshold: The optional threshold used to filter out the outliers. If the parameter is greater than zero, then all the point pairs that do not comply the epipolar geometry well enough (that is, the points for which :math:`|\texttt{points2[i]}^T*\texttt{F}*\texttt{points1[i]}|>\texttt{threshold}` ) are rejected prior to computing the homographies. - Otherwise all the points are considered inliers. - - :type threshold: float - - - -The function computes the rectification transformations without knowing intrinsic parameters of the cameras and their relative position in space, hence the suffix "Uncalibrated". Another related difference from -:ref:`StereoRectify` -is that the function outputs not the rectification transformations in the object (3D) space, but the planar perspective transformations, encoded by the homography matrices -``H1`` -and -``H2`` -. The function implements the algorithm -Hartley99 -. - -Note that while the algorithm does not need to know the intrinsic parameters of the cameras, it heavily depends on the epipolar geometry. Therefore, if the camera lenses have significant distortion, it would better be corrected before computing the fundamental matrix and calling this function. For example, distortion coefficients can be estimated for each head of stereo camera separately by using -:ref:`CalibrateCamera2` -and then the images can be corrected using -:ref:`Undistort2` -, or just the point coordinates can be corrected with -:ref:`UndistortPoints` -. - - - -.. index:: Undistort2 - -.. _Undistort2: - -Undistort2 ----------- - - - - -.. function:: Undistort2(src,dst,cameraMatrix,distCoeffs)-> None - - Transforms an image to compensate for lens distortion. - - - - - - - :param src: The input (distorted) image - - :type src: :class:`CvArr` - - - :param dst: The output (corrected) image; will have the same size and the same type as ``src`` - - :type dst: :class:`CvArr` - - - :param cameraMatrix: The input camera matrix :math:`A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` - - :type cameraMatrix: :class:`CvMat` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - :type distCoeffs: :class:`CvMat` - - - -The function transforms the image to compensate radial and tangential lens distortion. - -The function is simply a combination of -:ref:`InitUndistortRectifyMap` -(with unity -``R`` -) and -:ref:`Remap` -(with bilinear interpolation). See the former function for details of the transformation being performed. - -Those pixels in the destination image, for which there is no correspondent pixels in the source image, are filled with 0's (black color). - -The particular subset of the source image that will be visible in the corrected image can be regulated by -``newCameraMatrix`` -. You can use -:ref:`GetOptimalNewCameraMatrix` -to compute the appropriate -``newCameraMatrix`` -, depending on your requirements. - -The camera matrix and the distortion parameters can be determined using -:ref:`CalibrateCamera2` -. If the resolution of images is different from the used at the calibration stage, -:math:`f_x, f_y, c_x` -and -:math:`c_y` -need to be scaled accordingly, while the distortion coefficients remain the same. - - - -.. index:: UndistortPoints - -.. _UndistortPoints: - -UndistortPoints ---------------- - - - - -.. function:: UndistortPoints(src,dst,cameraMatrix,distCoeffs,R=NULL,P=NULL)-> None - - Computes the ideal point coordinates from the observed point coordinates. - - - - - - - :param src: The observed point coordinates, 1xN or Nx1 2-channel (CV _ 32FC2 or CV _ 64FC2). - - :type src: :class:`CvMat` - - - :param dst: The output ideal point coordinates, after undistortion and reverse perspective transformation , same format as ``src`` . - - :type dst: :class:`CvMat` - - - :param cameraMatrix: The camera matrix :math:`\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` - - :type cameraMatrix: :class:`CvMat` - - - :param distCoeffs: The input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5 or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - - :type distCoeffs: :class:`CvMat` - - - :param R: The rectification transformation in object space (3x3 matrix). ``R1`` or ``R2`` , computed by :cpp:func:`StereoRectify` can be passed here. If the matrix is empty, the identity transformation is used - - :type R: :class:`CvMat` - - - :param P: The new camera matrix (3x3) or the new projection matrix (3x4). ``P1`` or ``P2`` , computed by :cpp:func:`StereoRectify` can be passed here. If the matrix is empty, the identity new camera matrix is used - - :type P: :class:`CvMat` - - - -The function is similar to -:ref:`Undistort2` -and -:ref:`InitUndistortRectifyMap` -, but it operates on a sparse set of points instead of a raster image. Also the function does some kind of reverse transformation to -:ref:`ProjectPoints2` -(in the case of 3D object it will not reconstruct its 3D coordinates, of course; but for a planar object it will, up to a translation vector, if the proper -``R`` -is specified). - - - - -:: - - - - // (u,v) is the input point, (u', v') is the output point - // camera_matrix=[fx 0 cx; 0 fy cy; 0 0 1] - // P=[fx' 0 cx' tx; 0 fy' cy' ty; 0 0 1 tz] - x" = (u - cx)/fx - y" = (v - cy)/fy - (x',y') = undistort(x",y",dist_coeffs) - [X,Y,W]T = R*[x' y' 1]T - x = X/W, y = Y/W - u' = x*fx' + cx' - v' = y*fy' + cy', - - -.. - -where undistort() is approximate iterative algorithm that estimates the normalized original point coordinates out of the normalized distorted point coordinates ("normalized" means that the coordinates do not depend on the camera matrix). - -The function can be used both for a stereo camera head or for monocular camera (when R is -None -). diff --git a/doc/opencv1/py/cookbook.rst b/doc/opencv1/py/cookbook.rst deleted file mode 100644 index 6b4ed88c24..0000000000 --- a/doc/opencv1/py/cookbook.rst +++ /dev/null @@ -1,371 +0,0 @@ -Cookbook -======== - -.. highlight:: python - - -Here is a collection of code fragments demonstrating some features -of the OpenCV Python bindings. - - -Convert an image ----------------- - - - - - -.. doctest:: - - - - >>> import cv - >>> im = cv.LoadImageM("building.jpg") - >>> print type(im) - - >>> cv.SaveImage("foo.png", im) - - -.. - - -Resize an image ---------------- - - -To resize an image in OpenCV, create a destination image of the appropriate size, then call -:ref:`Resize` -. - - - - -.. doctest:: - - - - >>> import cv - >>> original = cv.LoadImageM("building.jpg") - >>> thumbnail = cv.CreateMat(original.rows / 10, original.cols / 10, cv.CV_8UC3) - >>> cv.Resize(original, thumbnail) - - -.. - - -Compute the Laplacian ---------------------- - - - - - -.. doctest:: - - - - >>> import cv - >>> im = cv.LoadImageM("building.jpg", 1) - >>> dst = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_16S, 3) - >>> laplace = cv.Laplace(im, dst) - >>> cv.SaveImage("foo-laplace.png", dst) - - -.. - - -Using GoodFeaturesToTrack -------------------------- - - -To find the 10 strongest corner features in an image, use -:ref:`GoodFeaturesToTrack` -like this: - - - - -.. doctest:: - - - - >>> import cv - >>> img = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE) - >>> eig_image = cv.CreateMat(img.rows, img.cols, cv.CV_32FC1) - >>> temp_image = cv.CreateMat(img.rows, img.cols, cv.CV_32FC1) - >>> for (x,y) in cv.GoodFeaturesToTrack(img, eig_image, temp_image, 10, 0.04, 1.0, useHarris = True): - ... print "good feature at", x,y - good feature at 198.0 514.0 - good feature at 791.0 260.0 - good feature at 370.0 467.0 - good feature at 374.0 469.0 - good feature at 490.0 520.0 - good feature at 262.0 278.0 - good feature at 781.0 134.0 - good feature at 3.0 247.0 - good feature at 667.0 321.0 - good feature at 764.0 304.0 - - -.. - - -Using GetSubRect ----------------- - - -GetSubRect returns a rectangular part of another image. It does this without copying any data. - - - - -.. doctest:: - - - - >>> import cv - >>> img = cv.LoadImageM("building.jpg") - >>> sub = cv.GetSubRect(img, (60, 70, 32, 32)) # sub is 32x32 patch within img - >>> cv.SetZero(sub) # clear sub to zero, which also clears 32x32 pixels in img - - -.. - - -Using CreateMat, and accessing an element ------------------------------------------ - - - - - -.. doctest:: - - - - >>> import cv - >>> mat = cv.CreateMat(5, 5, cv.CV_32FC1) - >>> cv.Set(mat, 1.0) - >>> mat[3,1] += 0.375 - >>> print mat[3,1] - 1.375 - >>> print [mat[3,i] for i in range(5)] - [1.0, 1.375, 1.0, 1.0, 1.0] - - -.. - - -ROS image message to OpenCV ---------------------------- - - -See this tutorial: -`Using CvBridge to convert between ROS images And OpenCV images `_ -. - - -PIL Image to OpenCV -------------------- - - -(For details on PIL see the -`PIL handbook `_ -.) - - - - -.. doctest:: - - - - >>> import Image, cv - >>> pi = Image.open('building.jpg') # PIL image - >>> cv_im = cv.CreateImageHeader(pi.size, cv.IPL_DEPTH_8U, 3) - >>> cv.SetData(cv_im, pi.tostring()) - >>> print pi.size, cv.GetSize(cv_im) - (868, 600) (868, 600) - >>> print pi.tostring() == cv_im.tostring() - True - - -.. - - -OpenCV to PIL Image -------------------- - - - - - -.. doctest:: - - - - >>> import Image, cv - >>> cv_im = cv.CreateImage((320,200), cv.IPL_DEPTH_8U, 1) - >>> pi = Image.fromstring("L", cv.GetSize(cv_im), cv_im.tostring()) - >>> print pi.size - (320, 200) - - -.. - - -NumPy and OpenCV ----------------- - - -Using the -`array interface `_ -, to use an OpenCV CvMat in NumPy: - - - - -.. doctest:: - - - - >>> import cv, numpy - >>> mat = cv.CreateMat(3, 5, cv.CV_32FC1) - >>> cv.Set(mat, 7) - >>> a = numpy.asarray(mat) - >>> print a - [[ 7. 7. 7. 7. 7.] - [ 7. 7. 7. 7. 7.] - [ 7. 7. 7. 7. 7.]] - - -.. - -and to use a NumPy array in OpenCV: - - - - -.. doctest:: - - - - >>> import cv, numpy - >>> a = numpy.ones((480, 640)) - >>> mat = cv.fromarray(a) - >>> print mat.rows - 480 - >>> print mat.cols - 640 - - -.. - -also, most OpenCV functions can work on NumPy arrays directly, for example: - - - - -.. doctest:: - - - - >>> picture = numpy.ones((640, 480)) - >>> cv.Smooth(picture, picture, cv.CV_GAUSSIAN, 15, 15) - - -.. - -Given a 2D array, -the -:ref:`fromarray` -function (or the implicit version shown above) -returns a single-channel -:ref:`CvMat` -of the same size. -For a 3D array of size -:math:`j \times k \times l` -, it returns a -:ref:`CvMat` -sized -:math:`j \times k` -with -:math:`l` -channels. - -Alternatively, use -:ref:`fromarray` -with the -``allowND`` -option to always return a -:ref:`cvMatND` -. - - -OpenCV to pygame ----------------- - - -To convert an OpenCV image to a -`pygame `_ -surface: - - - - -.. doctest:: - - - - >>> import pygame.image, cv - >>> src = cv.LoadImage("lena.jpg") - >>> src_rgb = cv.CreateMat(src.height, src.width, cv.CV_8UC3) - >>> cv.CvtColor(src, src_rgb, cv.CV_BGR2RGB) - >>> pg_img = pygame.image.frombuffer(src_rgb.tostring(), cv.GetSize(src_rgb), "RGB") - >>> print pg_img - - - -.. - - -OpenCV and OpenEXR ------------------- - - -Using -`OpenEXR's Python bindings `_ -you can make a simple -image viewer: - - - - -:: - - - - import OpenEXR, Imath, cv - filename = "GoldenGate.exr" - exrimage = OpenEXR.InputFile(filename) - - dw = exrimage.header()['dataWindow'] - (width, height) = (dw.max.x - dw.min.x + 1, dw.max.y - dw.min.y + 1) - - def fromstr(s): - mat = cv.CreateMat(height, width, cv.CV_32FC1) - cv.SetData(mat, s) - return mat - - pt = Imath.PixelType(Imath.PixelType.FLOAT) - (r, g, b) = [fromstr(s) for s in exrimage.channels("RGB", pt)] - - bgr = cv.CreateMat(height, width, cv.CV_32FC3) - cv.Merge(b, g, r, None, bgr) - - cv.ShowImage(filename, bgr) - cv.WaitKey() - - -.. - diff --git a/doc/opencv1/py/core.rst b/doc/opencv1/py/core.rst deleted file mode 100644 index 96da8cec77..0000000000 --- a/doc/opencv1/py/core.rst +++ /dev/null @@ -1,16 +0,0 @@ -**************************** -core. The Core Functionality -**************************** - - - -.. toctree:: - :maxdepth: 2 - - core_basic_structures - core_operations_on_arrays - core_dynamic_structures - core_drawing_functions - core_xml_yaml_persistence - core_clustering - core_utility_and_system_functions_and_macros diff --git a/doc/opencv1/py/core_basic_structures.rst b/doc/opencv1/py/core_basic_structures.rst deleted file mode 100644 index b226169ded..0000000000 --- a/doc/opencv1/py/core_basic_structures.rst +++ /dev/null @@ -1,520 +0,0 @@ -Basic Structures -================ - -.. highlight:: python - - - -.. index:: CvPoint - -.. _CvPoint: - -CvPoint -------- - - - -.. class:: CvPoint - - - -2D point with integer coordinates (usually zero-based). - -2D point, represented as a tuple -``(x, y)`` -, where x and y are integers. - -.. index:: CvPoint2D32f - -.. _CvPoint2D32f: - -CvPoint2D32f ------------- - - - -.. class:: CvPoint2D32f - - - -2D point with floating-point coordinates - -2D point, represented as a tuple -``(x, y)`` -, where x and y are floats. - -.. index:: CvPoint3D32f - -.. _CvPoint3D32f: - -CvPoint3D32f ------------- - - - -.. class:: CvPoint3D32f - - - -3D point with floating-point coordinates - -3D point, represented as a tuple -``(x, y, z)`` -, where x, y and z are floats. - -.. index:: CvPoint2D64f - -.. _CvPoint2D64f: - -CvPoint2D64f ------------- - - - -.. class:: CvPoint2D64f - - - -2D point with double precision floating-point coordinates - -2D point, represented as a tuple -``(x, y)`` -, where x and y are floats. - -.. index:: CvPoint3D64f - -.. _CvPoint3D64f: - -CvPoint3D64f ------------- - - - -.. class:: CvPoint3D64f - - - -3D point with double precision floating-point coordinates - -3D point, represented as a tuple -``(x, y, z)`` -, where x, y and z are floats. - -.. index:: CvSize - -.. _CvSize: - -CvSize ------- - - - -.. class:: CvSize - - - -Pixel-accurate size of a rectangle. - -Size of a rectangle, represented as a tuple -``(width, height)`` -, where width and height are integers. - -.. index:: CvSize2D32f - -.. _CvSize2D32f: - -CvSize2D32f ------------ - - - -.. class:: CvSize2D32f - - - -Sub-pixel accurate size of a rectangle. - -Size of a rectangle, represented as a tuple -``(width, height)`` -, where width and height are floats. - -.. index:: CvRect - -.. _CvRect: - -CvRect ------- - - - -.. class:: CvRect - - - -Offset (usually the top-left corner) and size of a rectangle. - -Rectangle, represented as a tuple -``(x, y, width, height)`` -, where all are integers. - -.. index:: CvScalar - -.. _CvScalar: - -CvScalar --------- - - - -.. class:: CvScalar - - - -A container for 1-,2-,3- or 4-tuples of doubles. - -CvScalar is always represented as a 4-tuple. - - - - -.. doctest:: - - - - >>> import cv - >>> cv.Scalar(1, 2, 3, 4) - (1.0, 2.0, 3.0, 4.0) - >>> cv.ScalarAll(7) - (7.0, 7.0, 7.0, 7.0) - >>> cv.RealScalar(7) - (7.0, 0.0, 0.0, 0.0) - >>> cv.RGB(17, 110, 255) - (255.0, 110.0, 17.0, 0.0) - - -.. - - -.. index:: CvTermCriteria - -.. _CvTermCriteria: - -CvTermCriteria --------------- - - - -.. class:: CvTermCriteria - - - -Termination criteria for iterative algorithms. - -Represented by a tuple -``(type, max_iter, epsilon)`` -. - - - - - - .. attribute:: type - - - - ``CV_TERMCRIT_ITER`` , ``CV_TERMCRIT_EPS`` or ``CV_TERMCRIT_ITER | CV_TERMCRIT_EPS`` - - - - .. attribute:: max_iter - - - - Maximum number of iterations - - - - .. attribute:: epsilon - - - - Required accuracy - - - - - - -:: - - - - (cv.CV_TERMCRIT_ITER, 10, 0) # terminate after 10 iterations - (cv.CV_TERMCRIT_EPS, 0, 0.01) # terminate when epsilon reaches 0.01 - (cv.CV_TERMCRIT_ITER | cv.CV_TERMCRIT_EPS, 10, 0.01) # terminate as soon as either condition is met - - -.. - - -.. index:: CvMat - -.. _CvMat: - -CvMat ------ - - - -.. class:: CvMat - - - -A multi-channel 2D matrix. Created by -:ref:`CreateMat` -, -:ref:`LoadImageM` -, -:ref:`CreateMatHeader` -, -:ref:`fromarray` -. - - - - - - .. attribute:: type - - - - A CvMat signature containing the type of elements and flags, int - - - - .. attribute:: step - - - - Full row length in bytes, int - - - - .. attribute:: rows - - - - Number of rows, int - - - - .. attribute:: cols - - - - Number of columns, int - - - - .. method:: tostring() -> str - - - - Returns the contents of the CvMat as a single string. - - - - -.. index:: CvMatND - -.. _CvMatND: - -CvMatND -------- - - - -.. class:: CvMatND - - - -Multi-dimensional dense multi-channel array. - - - - - - .. attribute:: type - - - - A CvMatND signature combining the type of elements and flags, int - - - - .. method:: tostring() -> str - - - - Returns the contents of the CvMatND as a single string. - - - - -.. index:: IplImage - -.. _IplImage: - -IplImage --------- - - - -.. class:: IplImage - - - -The -:ref:`IplImage` -object was inherited from the Intel Image Processing -Library, in which the format is native. OpenCV only supports a subset -of possible -:ref:`IplImage` -formats. - - - - - - .. attribute:: nChannels - - - - Number of channels, int. - - - - .. attribute:: width - - - - Image width in pixels - - - - .. attribute:: height - - - - Image height in pixels - - - - .. attribute:: depth - - - - Pixel depth in bits. The supported depths are: - - - .. attribute:: IPL_DEPTH_8U - - - - Unsigned 8-bit integer - - - .. attribute:: IPL_DEPTH_8S - - - - Signed 8-bit integer - - - .. attribute:: IPL_DEPTH_16U - - - - Unsigned 16-bit integer - - - .. attribute:: IPL_DEPTH_16S - - - - Signed 16-bit integer - - - .. attribute:: IPL_DEPTH_32S - - - - Signed 32-bit integer - - - .. attribute:: IPL_DEPTH_32F - - - - Single-precision floating point - - - .. attribute:: IPL_DEPTH_64F - - - - Double-precision floating point - - - - - - .. attribute:: origin - - - - 0 - top-left origin, 1 - bottom-left origin (Windows bitmap style) - - - - .. method:: tostring() -> str - - - - Returns the contents of the CvMatND as a single string. - - - - -.. index:: CvArr - -.. _CvArr: - -CvArr ------ - - - -.. class:: CvArr - - - -Arbitrary array - -``CvArr`` -is used -*only* -as a function parameter to specify that the parameter can be: - - - - -* an :ref:`IplImage` - - -* a :ref:`CvMat` - - -* any other type that exports the `array interface `_ - - diff --git a/doc/opencv1/py/core_clustering.rst b/doc/opencv1/py/core_clustering.rst deleted file mode 100644 index c4ff3e863c..0000000000 --- a/doc/opencv1/py/core_clustering.rst +++ /dev/null @@ -1,60 +0,0 @@ -Clustering -========== - -.. highlight:: python - - - -.. index:: KMeans2 - -.. _KMeans2: - -KMeans2 -------- - - - - -.. function:: KMeans2(samples,nclusters,labels,termcrit)-> None - - Splits set of vectors by a given number of clusters. - - - - - - - :param samples: Floating-point matrix of input samples, one row per sample - - :type samples: :class:`CvArr` - - - :param nclusters: Number of clusters to split the set by - - :type nclusters: int - - - :param labels: Output integer vector storing cluster indices for every sample - - :type labels: :class:`CvArr` - - - :param termcrit: Specifies maximum number of iterations and/or accuracy (distance the centers can move by between subsequent iterations) - - :type termcrit: :class:`CvTermCriteria` - - - -The function -``cvKMeans2`` -implements a k-means algorithm that finds the -centers of -``nclusters`` -clusters and groups the input samples -around the clusters. On output, -:math:`\texttt{labels}_i` -contains a cluster index for -samples stored in the i-th row of the -``samples`` -matrix. - diff --git a/doc/opencv1/py/core_drawing_functions.rst b/doc/opencv1/py/core_drawing_functions.rst deleted file mode 100644 index 85ff38d4ed..0000000000 --- a/doc/opencv1/py/core_drawing_functions.rst +++ /dev/null @@ -1,967 +0,0 @@ -Drawing Functions -================= - -.. highlight:: python - - -Drawing functions work with matrices/images of arbitrary depth. -The boundaries of the shapes can be rendered with antialiasing (implemented only for 8-bit images for now). -All the functions include the parameter color that uses a rgb value (that may be constructed -with -``CV_RGB`` -) for color -images and brightness for grayscale images. For color images the order channel -is normally -*Blue, Green, Red* -, this is what -:cpp:func:`imshow` -, -:cpp:func:`imread` -and -:cpp:func:`imwrite` -expect -If you are using your own image rendering and I/O functions, you can use any channel ordering, the drawing functions process each channel independently and do not depend on the channel order or even on the color space used. The whole image can be converted from BGR to RGB or to a different color space using -:cpp:func:`cvtColor` -. - -If a drawn figure is partially or completely outside the image, the drawing functions clip it. Also, many drawing functions can handle pixel coordinates specified with sub-pixel accuracy, that is, the coordinates can be passed as fixed-point numbers, encoded as integers. The number of fractional bits is specified by the -``shift`` -parameter and the real point coordinates are calculated as -:math:`\texttt{Point}(x,y)\rightarrow\texttt{Point2f}(x*2^{-shift},y*2^{-shift})` -. This feature is especially effective wehn rendering antialiased shapes. - -Also, note that the functions do not support alpha-transparency - when the target image is 4-channnel, then the -``color[3]`` -is simply copied to the repainted pixels. Thus, if you want to paint semi-transparent shapes, you can paint them in a separate buffer and then blend it with the main image. - - -.. index:: Circle - -.. _Circle: - -Circle ------- - - - - -.. function:: Circle(img,center,radius,color,thickness=1,lineType=8,shift=0)-> None - - Draws a circle. - - - - - - - :param img: Image where the circle is drawn - - :type img: :class:`CvArr` - - - :param center: Center of the circle - - :type center: :class:`CvPoint` - - - :param radius: Radius of the circle - - :type radius: int - - - :param color: Circle color - - :type color: :class:`CvScalar` - - - :param thickness: Thickness of the circle outline if positive, otherwise this indicates that a filled circle is to be drawn - - :type thickness: int - - - :param lineType: Type of the circle boundary, see :ref:`Line` description - - :type lineType: int - - - :param shift: Number of fractional bits in the center coordinates and radius value - - :type shift: int - - - -The function draws a simple or filled circle with a -given center and radius. - - -.. index:: ClipLine - -.. _ClipLine: - -ClipLine --------- - - - - -.. function:: ClipLine(imgSize, pt1, pt2) -> (clipped_pt1, clipped_pt2) - - Clips the line against the image rectangle. - - - - - - - :param imgSize: Size of the image - - :type imgSize: :class:`CvSize` - - - :param pt1: First ending point of the line segment. - - :type pt1: :class:`CvPoint` - - - :param pt2: Second ending point of the line segment. - - :type pt2: :class:`CvPoint` - - - -The function calculates a part of the line segment which is entirely within the image. -If the line segment is outside the image, it returns None. If the line segment is inside the image it returns a new pair of points. - -.. index:: DrawContours - -.. _DrawContours: - -DrawContours ------------- - - - - -.. function:: DrawContours(img,contour,external_color,hole_color,max_level,thickness=1,lineType=8,offset=(0,0))-> None - - Draws contour outlines or interiors in an image. - - - - - - - :param img: Image where the contours are to be drawn. As with any other drawing function, the contours are clipped with the ROI. - - :type img: :class:`CvArr` - - - :param contour: Pointer to the first contour - - :type contour: :class:`CvSeq` - - - :param external_color: Color of the external contours - - :type external_color: :class:`CvScalar` - - - :param hole_color: Color of internal contours (holes) - - :type hole_color: :class:`CvScalar` - - - :param max_level: Maximal level for drawn contours. If 0, only ``contour`` is drawn. If 1, the contour and all contours following - it on the same level are drawn. If 2, all contours following and all - contours one level below the contours are drawn, and so forth. If the value - is negative, the function does not draw the contours following after ``contour`` but draws the child contours of ``contour`` up - to the :math:`|\texttt{max\_level}|-1` level. - - :type max_level: int - - - :param thickness: Thickness of lines the contours are drawn with. - If it is negative (For example, =CV _ FILLED), the contour interiors are - drawn. - - :type thickness: int - - - :param lineType: Type of the contour segments, see :ref:`Line` description - - :type lineType: int - - - -The function draws contour outlines in the image if -:math:`\texttt{thickness} \ge 0` -or fills the area bounded by the contours if -:math:`\texttt{thickness}<0` -. - - -.. index:: Ellipse - -.. _Ellipse: - -Ellipse -------- - - - - -.. function:: Ellipse(img,center,axes,angle,start_angle,end_angle,color,thickness=1,lineType=8,shift=0)-> None - - Draws a simple or thick elliptic arc or an fills ellipse sector. - - - - - - - :param img: The image - - :type img: :class:`CvArr` - - - :param center: Center of the ellipse - - :type center: :class:`CvPoint` - - - :param axes: Length of the ellipse axes - - :type axes: :class:`CvSize` - - - :param angle: Rotation angle - - :type angle: float - - - :param start_angle: Starting angle of the elliptic arc - - :type start_angle: float - - - :param end_angle: Ending angle of the elliptic arc. - - :type end_angle: float - - - :param color: Ellipse color - - :type color: :class:`CvScalar` - - - :param thickness: Thickness of the ellipse arc outline if positive, otherwise this indicates that a filled ellipse sector is to be drawn - - :type thickness: int - - - :param lineType: Type of the ellipse boundary, see :ref:`Line` description - - :type lineType: int - - - :param shift: Number of fractional bits in the center coordinates and axes' values - - :type shift: int - - - -The function draws a simple or thick elliptic -arc or fills an ellipse sector. The arc is clipped by the ROI rectangle. -A piecewise-linear approximation is used for antialiased arcs and -thick arcs. All the angles are given in degrees. The picture below -explains the meaning of the parameters. - -Parameters of Elliptic Arc - - - -.. image:: ../pics/ellipse.png - - - - -.. index:: EllipseBox - -.. _EllipseBox: - -EllipseBox ----------- - - - - -.. function:: EllipseBox(img,box,color,thickness=1,lineType=8,shift=0)-> None - - Draws a simple or thick elliptic arc or fills an ellipse sector. - - - - - - - :param img: Image - - :type img: :class:`CvArr` - - - :param box: The enclosing box of the ellipse drawn - - :type box: :class:`CvBox2D` - - - :param thickness: Thickness of the ellipse boundary - - :type thickness: int - - - :param lineType: Type of the ellipse boundary, see :ref:`Line` description - - :type lineType: int - - - :param shift: Number of fractional bits in the box vertex coordinates - - :type shift: int - - - -The function draws a simple or thick ellipse outline, or fills an ellipse. The functions provides a convenient way to draw an ellipse approximating some shape; that is what -:ref:`CamShift` -and -:ref:`FitEllipse` -do. The ellipse drawn is clipped by ROI rectangle. A piecewise-linear approximation is used for antialiased arcs and thick arcs. - - -.. index:: FillConvexPoly - -.. _FillConvexPoly: - -FillConvexPoly --------------- - - - - -.. function:: FillConvexPoly(img,pn,color,lineType=8,shift=0)-> None - - Fills a convex polygon. - - - - - - - :param img: Image - - :type img: :class:`CvArr` - - - :param pn: List of coordinate pairs - - :type pn: :class:`CvPoints` - - - :param color: Polygon color - - :type color: :class:`CvScalar` - - - :param lineType: Type of the polygon boundaries, see :ref:`Line` description - - :type lineType: int - - - :param shift: Number of fractional bits in the vertex coordinates - - :type shift: int - - - -The function fills a convex polygon's interior. -This function is much faster than the function -``cvFillPoly`` -and can fill not only convex polygons but any monotonic polygon, -i.e., a polygon whose contour intersects every horizontal line (scan -line) twice at the most. - - - -.. index:: FillPoly - -.. _FillPoly: - -FillPoly --------- - - - - -.. function:: FillPoly(img,polys,color,lineType=8,shift=0)-> None - - Fills a polygon's interior. - - - - - - - :param img: Image - - :type img: :class:`CvArr` - - - :param polys: List of lists of (x,y) pairs. Each list of points is a polygon. - - :type polys: list of lists of (x,y) pairs - - - :param color: Polygon color - - :type color: :class:`CvScalar` - - - :param lineType: Type of the polygon boundaries, see :ref:`Line` description - - :type lineType: int - - - :param shift: Number of fractional bits in the vertex coordinates - - :type shift: int - - - -The function fills an area bounded by several -polygonal contours. The function fills complex areas, for example, -areas with holes, contour self-intersection, and so forth. - - -.. index:: GetTextSize - -.. _GetTextSize: - -GetTextSize ------------ - - - - -.. function:: GetTextSize(textString,font)-> (textSize,baseline) - - Retrieves the width and height of a text string. - - - - - - - :param font: Pointer to the font structure - - :type font: :class:`CvFont` - - - :param textString: Input string - - :type textString: str - - - :param textSize: Resultant size of the text string. Height of the text does not include the height of character parts that are below the baseline. - - :type textSize: :class:`CvSize` - - - :param baseline: y-coordinate of the baseline relative to the bottom-most text point - - :type baseline: int - - - -The function calculates the dimensions of a rectangle to enclose a text string when a specified font is used. - - -.. index:: InitFont - -.. _InitFont: - -InitFont --------- - - - - -.. function:: InitFont(fontFace,hscale,vscale,shear=0,thickness=1,lineType=8)-> font - - Initializes font structure. - - - - - - - :param font: Pointer to the font structure initialized by the function - - :type font: :class:`CvFont` - - - :param fontFace: Font name identifier. Only a subset of Hershey fonts http://sources.isc.org/utils/misc/hershey-font.txt are supported now: - - - - * **CV_FONT_HERSHEY_SIMPLEX** normal size sans-serif font - - - * **CV_FONT_HERSHEY_PLAIN** small size sans-serif font - - - * **CV_FONT_HERSHEY_DUPLEX** normal size sans-serif font (more complex than ``CV_FONT_HERSHEY_SIMPLEX`` ) - - - * **CV_FONT_HERSHEY_COMPLEX** normal size serif font - - - * **CV_FONT_HERSHEY_TRIPLEX** normal size serif font (more complex than ``CV_FONT_HERSHEY_COMPLEX`` ) - - - * **CV_FONT_HERSHEY_COMPLEX_SMALL** smaller version of ``CV_FONT_HERSHEY_COMPLEX`` - - - * **CV_FONT_HERSHEY_SCRIPT_SIMPLEX** hand-writing style font - - - * **CV_FONT_HERSHEY_SCRIPT_COMPLEX** more complex variant of ``CV_FONT_HERSHEY_SCRIPT_SIMPLEX`` - - - - The parameter can be composited from one of the values above and an optional ``CV_FONT_ITALIC`` flag, which indicates italic or oblique font. - - :type fontFace: int - - - :param hscale: Horizontal scale. If equal to ``1.0f`` , the characters have the original width depending on the font type. If equal to ``0.5f`` , the characters are of half the original width. - - :type hscale: float - - - :param vscale: Vertical scale. If equal to ``1.0f`` , the characters have the original height depending on the font type. If equal to ``0.5f`` , the characters are of half the original height. - - :type vscale: float - - - :param shear: Approximate tangent of the character slope relative to the vertical line. A zero value means a non-italic font, ``1.0f`` means about a 45 degree slope, etc. - - :type shear: float - - - :param thickness: Thickness of the text strokes - - :type thickness: int - - - :param lineType: Type of the strokes, see :ref:`Line` description - - :type lineType: int - - - -The function initializes the font structure that can be passed to text rendering functions. - - - -.. index:: InitLineIterator - -.. _InitLineIterator: - -InitLineIterator ----------------- - - - - -.. function:: InitLineIterator(image, pt1, pt2, connectivity=8, left_to_right=0) -> line_iterator - - Initializes the line iterator. - - - - - - - :param image: Image to sample the line from - - :type image: :class:`CvArr` - - - :param pt1: First ending point of the line segment - - :type pt1: :class:`CvPoint` - - - :param pt2: Second ending point of the line segment - - :type pt2: :class:`CvPoint` - - - :param connectivity: The scanned line connectivity, 4 or 8. - - :type connectivity: int - - - :param left_to_right: - If ( :math:`\texttt{left\_to\_right} = 0` ) then the line is scanned in the specified order, from ``pt1`` to ``pt2`` . - If ( :math:`\texttt{left\_to\_right} \ne 0` ) the line is scanned from left-most point to right-most. - - :type left_to_right: int - - - :param line_iterator: Iterator over the pixels of the line - - :type line_iterator: :class:`iter` - - - -The function returns an iterator over the pixels connecting the two points. -The points on the line are -calculated one by one using a 4-connected or 8-connected Bresenham -algorithm. - -Example: Using line iterator to calculate the sum of pixel values along a color line - - - - -.. doctest:: - - - - >>> import cv - >>> img = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_COLOR) - >>> li = cv.InitLineIterator(img, (100, 100), (125, 150)) - >>> red_sum = 0 - >>> green_sum = 0 - >>> blue_sum = 0 - >>> for (r, g, b) in li: - ... red_sum += r - ... green_sum += g - ... blue_sum += b - >>> print red_sum, green_sum, blue_sum - 10935.0 9496.0 7946.0 - - -.. - -or more concisely using -`zip `_ -: - - - - -.. doctest:: - - - - >>> import cv - >>> img = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_COLOR) - >>> li = cv.InitLineIterator(img, (100, 100), (125, 150)) - >>> print [sum(c) for c in zip(*li)] - [10935.0, 9496.0, 7946.0] - - -.. - - -.. index:: Line - -.. _Line: - -Line ----- - - - - -.. function:: Line(img,pt1,pt2,color,thickness=1,lineType=8,shift=0)-> None - - Draws a line segment connecting two points. - - - - - - - :param img: The image - - :type img: :class:`CvArr` - - - :param pt1: First point of the line segment - - :type pt1: :class:`CvPoint` - - - :param pt2: Second point of the line segment - - :type pt2: :class:`CvPoint` - - - :param color: Line color - - :type color: :class:`CvScalar` - - - :param thickness: Line thickness - - :type thickness: int - - - :param lineType: Type of the line: - - - - * **8** (or omitted) 8-connected line. - - - * **4** 4-connected line. - - - * **CV_AA** antialiased line. - - - - - :type lineType: int - - - :param shift: Number of fractional bits in the point coordinates - - :type shift: int - - - -The function draws the line segment between -``pt1`` -and -``pt2`` -points in the image. The line is -clipped by the image or ROI rectangle. For non-antialiased lines -with integer coordinates the 8-connected or 4-connected Bresenham -algorithm is used. Thick lines are drawn with rounding endings. -Antialiased lines are drawn using Gaussian filtering. To specify -the line color, the user may use the macro -``CV_RGB( r, g, b )`` -. - - -.. index:: PolyLine - -.. _PolyLine: - -PolyLine --------- - - - - -.. function:: PolyLine(img,polys,is_closed,color,thickness=1,lineType=8,shift=0)-> None - - Draws simple or thick polygons. - - - - - - - :param polys: List of lists of (x,y) pairs. Each list of points is a polygon. - - :type polys: list of lists of (x,y) pairs - - - :param img: Image - - :type img: :class:`CvArr` - - - :param is_closed: Indicates whether the polylines must be drawn - closed. If closed, the function draws the line from the last vertex - of every contour to the first vertex. - - :type is_closed: int - - - :param color: Polyline color - - :type color: :class:`CvScalar` - - - :param thickness: Thickness of the polyline edges - - :type thickness: int - - - :param lineType: Type of the line segments, see :ref:`Line` description - - :type lineType: int - - - :param shift: Number of fractional bits in the vertex coordinates - - :type shift: int - - - -The function draws single or multiple polygonal curves. - - -.. index:: PutText - -.. _PutText: - -PutText -------- - - - - -.. function:: PutText(img,text,org,font,color)-> None - - Draws a text string. - - - - - - - :param img: Input image - - :type img: :class:`CvArr` - - - :param text: String to print - - :type text: str - - - :param org: Coordinates of the bottom-left corner of the first letter - - :type org: :class:`CvPoint` - - - :param font: Pointer to the font structure - - :type font: :class:`CvFont` - - - :param color: Text color - - :type color: :class:`CvScalar` - - - -The function renders the text in the image with -the specified font and color. The printed text is clipped by the ROI -rectangle. Symbols that do not belong to the specified font are -replaced with the symbol for a rectangle. - - -.. index:: Rectangle - -.. _Rectangle: - -Rectangle ---------- - - - - -.. function:: Rectangle(img,pt1,pt2,color,thickness=1,lineType=8,shift=0)-> None - - Draws a simple, thick, or filled rectangle. - - - - - - - :param img: Image - - :type img: :class:`CvArr` - - - :param pt1: One of the rectangle's vertices - - :type pt1: :class:`CvPoint` - - - :param pt2: Opposite rectangle vertex - - :type pt2: :class:`CvPoint` - - - :param color: Line color (RGB) or brightness (grayscale image) - - :type color: :class:`CvScalar` - - - :param thickness: Thickness of lines that make up the rectangle. Negative values, e.g., CV _ FILLED, cause the function to draw a filled rectangle. - - :type thickness: int - - - :param lineType: Type of the line, see :ref:`Line` description - - :type lineType: int - - - :param shift: Number of fractional bits in the point coordinates - - :type shift: int - - - -The function draws a rectangle with two opposite corners -``pt1`` -and -``pt2`` -. - - -.. index:: CV_RGB - -.. _CV_RGB: - -CV_RGB ------- - - - - -.. function:: CV_RGB(red,grn,blu)->CvScalar - - Constructs a color value. - - - - - - - :param red: Red component - - :type red: float - - - :param grn: Green component - - :type grn: float - - - :param blu: Blue component - - :type blu: float - - - diff --git a/doc/opencv1/py/core_dynamic_structures.rst b/doc/opencv1/py/core_dynamic_structures.rst deleted file mode 100644 index 9ec65aca39..0000000000 --- a/doc/opencv1/py/core_dynamic_structures.rst +++ /dev/null @@ -1,295 +0,0 @@ -Dynamic Structures -================== - -.. highlight:: python - - - -.. index:: CvMemStorage - -.. _CvMemStorage: - -CvMemStorage ------------- - - - -.. class:: CvMemStorage - - - -Growing memory storage. - -Many OpenCV functions use a given storage area for their results -and working storage. These storage areas can be created using -:ref:`CreateMemStorage` -. OpenCV Python tracks the objects occupying a -CvMemStorage, and automatically releases the CvMemStorage when there are -no objects referring to it. For this reason, there is explicit function -to release a CvMemStorage. - - - - -.. doctest:: - - - - >>> import cv - >>> image = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE) - >>> seq = cv.FindContours(image, cv.CreateMemStorage(), cv.CV_RETR_TREE, cv.CV_CHAIN_APPROX_SIMPLE) - >>> del seq # associated storage is also released - - -.. - - -.. index:: CvSeq - -.. _CvSeq: - -CvSeq ------ - - - -.. class:: CvSeq - - - -Growable sequence of elements. - -Many OpenCV functions return a CvSeq object. The CvSeq obect is a sequence, so these are all legal: - - - -:: - - - - seq = cv.FindContours(scribble, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) - # seq is a sequence of point pairs - print len(seq) - # FindContours returns a sequence of (x,y) points, so to print them out: - for (x,y) in seq: - print (x,y) - print seq[10] # tenth entry in the seqeuence - print seq[::-1] # reversed sequence - print sorted(list(seq)) # sorted sequence - - -.. - -Also, a CvSeq object has methods -``h_next()`` -, -``h_prev()`` -, -``v_next()`` -and -``v_prev()`` -. -Some OpenCV functions (for example -:ref:`FindContours` -) can return multiple CvSeq objects, connected by these relations. -In this case the methods return the other sequences. If no relation between sequences exists, then the methods return -``None`` -. - - -.. index:: CvSet - -.. _CvSet: - -CvSet ------ - - - -.. class:: CvSet - - - -Collection of nodes. - -Some OpenCV functions return a CvSet object. The CvSet obect is iterable, for example: - - - - -:: - - - - for i in s: - print i - print set(s) - print list(s) - - -.. - - -.. index:: CloneSeq - -.. _CloneSeq: - -CloneSeq --------- - - - - -.. function:: CloneSeq(seq,storage)-> None - - Creates a copy of a sequence. - - - - - - - :param seq: Sequence - - :type seq: :class:`CvSeq` - - - :param storage: The destination storage block to hold the new sequence header and the copied data, if any. If it is NULL, the function uses the storage block containing the input sequence. - - :type storage: :class:`CvMemStorage` - - - -The function makes a complete copy of the input sequence and returns it. - - -.. index:: CreateMemStorage - -.. _CreateMemStorage: - -CreateMemStorage ----------------- - - - - -.. function:: CreateMemStorage(blockSize = 0) -> memstorage - - Creates memory storage. - - - - - - - :param blockSize: Size of the storage blocks in bytes. If it is 0, the block size is set to a default value - currently it is about 64K. - - :type blockSize: int - - - -The function creates an empty memory storage. See -:ref:`CvMemStorage` -description. - - -.. index:: SeqInvert - -.. _SeqInvert: - -SeqInvert ---------- - - - - -.. function:: SeqInvert(seq)-> None - - Reverses the order of sequence elements. - - - - - - - :param seq: Sequence - - :type seq: :class:`CvSeq` - - - -The function reverses the sequence in-place - makes the first element go last, the last element go first and so forth. - - -.. index:: SeqRemove - -.. _SeqRemove: - -SeqRemove ---------- - - - - -.. function:: SeqRemove(seq,index)-> None - - Removes an element from the middle of a sequence. - - - - - - - :param seq: Sequence - - :type seq: :class:`CvSeq` - - - :param index: Index of removed element - - :type index: int - - - -The function removes elements with the given -index. If the index is out of range the function reports an error. An -attempt to remove an element from an empty sequence is a special -case of this situation. The function removes an element by shifting -the sequence elements between the nearest end of the sequence and the -``index`` --th position, not counting the latter. - - - -.. index:: SeqRemoveSlice - -.. _SeqRemoveSlice: - -SeqRemoveSlice --------------- - - - - -.. function:: SeqRemoveSlice(seq,slice)-> None - - Removes a sequence slice. - - - - - - - :param seq: Sequence - - :type seq: :class:`CvSeq` - - - :param slice: The part of the sequence to remove - - :type slice: :class:`CvSlice` - - - -The function removes a slice from the sequence. - diff --git a/doc/opencv1/py/core_operations_on_arrays.rst b/doc/opencv1/py/core_operations_on_arrays.rst deleted file mode 100644 index de811ef7d0..0000000000 --- a/doc/opencv1/py/core_operations_on_arrays.rst +++ /dev/null @@ -1,6914 +0,0 @@ -Operations on Arrays -==================== - -.. highlight:: python - - - -.. index:: AbsDiff - -.. _AbsDiff: - -AbsDiff -------- - - - - -.. function:: AbsDiff(src1,src2,dst)-> None - - Calculates absolute difference between two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - -The function calculates absolute difference between two arrays. - - - -.. math:: - - \texttt{dst} (i)_c = | \texttt{src1} (I)_c - \texttt{src2} (I)_c| - - -All the arrays must have the same data type and the same size (or ROI size). - - -.. index:: AbsDiffS - -.. _AbsDiffS: - -AbsDiffS --------- - - - - -.. function:: AbsDiffS(src,dst,value)-> None - - Calculates absolute difference between an array and a scalar. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param value: The scalar - - :type value: :class:`CvScalar` - - - -The function calculates absolute difference between an array and a scalar. - - - -.. math:: - - \texttt{dst} (i)_c = | \texttt{src} (I)_c - \texttt{value} _c| - - -All the arrays must have the same data type and the same size (or ROI size). - - - -.. index:: Add - -.. _Add: - -Add ---- - - - - -.. function:: Add(src1,src2,dst,mask=NULL)-> None - - Computes the per-element sum of two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function adds one array to another: - - - - -:: - - - - dst(I)=src1(I)+src2(I) if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). -For types that have limited range this operation is saturating. - - -.. index:: AddS - -.. _AddS: - -AddS ----- - - - - -.. function:: AddS(src,value,dst,mask=NULL)-> None - - Computes the sum of an array and a scalar. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param value: Added scalar - - :type value: :class:`CvScalar` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function adds a scalar -``value`` -to every element in the source array -``src1`` -and stores the result in -``dst`` -. -For types that have limited range this operation is saturating. - - - - -:: - - - - dst(I)=src(I)+value if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). - - - -.. index:: AddWeighted - -.. _AddWeighted: - -AddWeighted ------------ - - - - -.. function:: AddWeighted(src1,alpha,src2,beta,gamma,dst)-> None - - Computes the weighted sum of two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param alpha: Weight for the first array elements - - :type alpha: float - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param beta: Weight for the second array elements - - :type beta: float - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param gamma: Scalar, added to each sum - - :type gamma: float - - - -The function calculates the weighted sum of two arrays as follows: - - - - -:: - - - - dst(I)=src1(I)*alpha+src2(I)*beta+gamma - - -.. - -All the arrays must have the same type and the same size (or ROI size). -For types that have limited range this operation is saturating. - - - -.. index:: And - -.. _And: - -And ---- - - - - -.. function:: And(src1,src2,dst,mask=NULL)-> None - - Calculates per-element bit-wise conjunction of two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function calculates per-element bit-wise logical conjunction of two arrays: - - - - -:: - - - - dst(I)=src1(I)&src2(I) if mask(I)!=0 - - -.. - -In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - -.. index:: AndS - -.. _AndS: - -AndS ----- - - - - -.. function:: AndS(src,value,dst,mask=NULL)-> None - - Calculates per-element bit-wise conjunction of an array and a scalar. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param value: Scalar to use in the operation - - :type value: :class:`CvScalar` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function calculates per-element bit-wise conjunction of an array and a scalar: - - - - -:: - - - - dst(I)=src(I)&value if mask(I)!=0 - - -.. - -Prior to the actual operation, the scalar is converted to the same type as that of the array(s). In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - -.. index:: Avg - -.. _Avg: - -Avg ---- - - - - -.. function:: Avg(arr,mask=NULL)-> CvScalar - - Calculates average (mean) of array elements. - - - - - - - :param arr: The array - - :type arr: :class:`CvArr` - - - :param mask: The optional operation mask - - :type mask: :class:`CvArr` - - - -The function calculates the average value -``M`` -of array elements, independently for each channel: - - - -.. math:: - - \begin{array}{l} N = \sum _I ( \texttt{mask} (I) \ne 0) \\ M_c = \frac{\sum_{I, \, \texttt{mask}(I) \ne 0} \texttt{arr} (I)_c}{N} \end{array} - - -If the array is -``IplImage`` -and COI is set, the function processes the selected channel only and stores the average to the first scalar component -:math:`S_0` -. - - -.. index:: AvgSdv - -.. _AvgSdv: - -AvgSdv ------- - - - - -.. function:: AvgSdv(arr,mask=NULL)-> (mean, stdDev) - - Calculates average (mean) of array elements. - - - - - - - :param arr: The array - - :type arr: :class:`CvArr` - - - :param mask: The optional operation mask - - :type mask: :class:`CvArr` - - - :param mean: Mean value, a CvScalar - - :type mean: :class:`CvScalar` - - - :param stdDev: Standard deviation, a CvScalar - - :type stdDev: :class:`CvScalar` - - - -The function calculates the average value and standard deviation of array elements, independently for each channel: - - - -.. math:: - - \begin{array}{l} N = \sum _I ( \texttt{mask} (I) \ne 0) \\ mean_c = \frac{1}{N} \, \sum _{ I, \, \texttt{mask} (I) \ne 0} \texttt{arr} (I)_c \\ stdDev_c = \sqrt{\frac{1}{N} \, \sum_{ I, \, \texttt{mask}(I) \ne 0} ( \texttt{arr} (I)_c - mean_c)^2} \end{array} - - -If the array is -``IplImage`` -and COI is set, the function processes the selected channel only and stores the average and standard deviation to the first components of the output scalars ( -:math:`mean_0` -and -:math:`stdDev_0` -). - - -.. index:: CalcCovarMatrix - -.. _CalcCovarMatrix: - -CalcCovarMatrix ---------------- - - - - -.. function:: CalcCovarMatrix(vects,covMat,avg,flags)-> None - - Calculates covariance matrix of a set of vectors. - - - - - - - :param vects: The input vectors, all of which must have the same type and the same size. The vectors do not have to be 1D, they can be 2D (e.g., images) and so forth - - :type vects: :class:`cvarr_count` - - - :param covMat: The output covariance matrix that should be floating-point and square - - :type covMat: :class:`CvArr` - - - :param avg: The input or output (depending on the flags) array - the mean (average) vector of the input vectors - - :type avg: :class:`CvArr` - - - :param flags: The operation flags, a combination of the following values - - * **CV_COVAR_SCRAMBLED** The output covariance matrix is calculated as: - - .. math:: - - \texttt{scale} * [ \texttt{vects} [0]- \texttt{avg} , \texttt{vects} [1]- \texttt{avg} ,...]^T \cdot [ \texttt{vects} [0]- \texttt{avg} , \texttt{vects} [1]- \texttt{avg} ,...] - - , - that is, the covariance matrix is :math:`\texttt{count} \times \texttt{count}` . - 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 will - match the eigenvalues of the true covariance matrix and the "true" - eigenvectors can be easily calculated from the eigenvectors of the - "scrambled" covariance matrix. - - * **CV_COVAR_NORMAL** The output covariance matrix is calculated as: - - .. math:: - - \texttt{scale} * [ \texttt{vects} [0]- \texttt{avg} , \texttt{vects} [1]- \texttt{avg} ,...] \cdot [ \texttt{vects} [0]- \texttt{avg} , \texttt{vects} [1]- \texttt{avg} ,...]^T - - , - that is, ``covMat`` will be a covariance matrix - with the same linear size as the total number of elements in each - input vector. One and only one of ``CV_COVAR_SCRAMBLED`` and ``CV_COVAR_NORMAL`` must be specified - - * **CV_COVAR_USE_AVG** If the flag is specified, the function does not calculate ``avg`` from the input vectors, but, instead, uses the passed ``avg`` vector. This is useful if ``avg`` has been already calculated somehow, or if the covariance matrix is calculated by parts - in this case, ``avg`` is not a mean vector of the input sub-set of vectors, but rather the mean vector of the whole set. - - * **CV_COVAR_SCALE** If the flag is specified, the covariance matrix is scaled. In the "normal" mode ``scale`` is '1./count'; 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'). - - - * **CV_COVAR_ROWS** Means that all the input vectors are stored as rows of a single matrix, ``vects[0]`` . ``count`` is ignored in this case, and ``avg`` should be a single-row vector of an appropriate size. - - * **CV_COVAR_COLS** Means that all the input vectors are stored as columns of a single matrix, ``vects[0]`` . ``count`` is ignored in this case, and ``avg`` should be a single-column vector of an appropriate size. - - - - - :type flags: int - - - -The function calculates the covariance matrix -and, optionally, the mean vector of the set of input vectors. The function -can be used for PCA, for comparing vectors using Mahalanobis distance and so forth. - - -.. index:: CartToPolar - -.. _CartToPolar: - -CartToPolar ------------ - - - - -.. function:: CartToPolar(x,y,magnitude,angle=NULL,angleInDegrees=0)-> None - - Calculates the magnitude and/or angle of 2d vectors. - - - - - - - :param x: The array of x-coordinates - - :type x: :class:`CvArr` - - - :param y: The array of y-coordinates - - :type y: :class:`CvArr` - - - :param magnitude: The destination array of magnitudes, may be set to NULL if it is not needed - - :type magnitude: :class:`CvArr` - - - :param angle: The destination array of angles, may be set to NULL if it is not needed. The angles are measured in radians :math:`(0` to :math:`2 \pi )` or in degrees (0 to 360 degrees). - - :type angle: :class:`CvArr` - - - :param angleInDegrees: The flag indicating whether the angles are measured in radians, which is default mode, or in degrees - - :type angleInDegrees: int - - - -The function calculates either the magnitude, angle, or both of every 2d vector (x(I),y(I)): - - - - -:: - - - - - magnitude(I)=sqrt(x(I)^2^+y(I)^2^ ), - angle(I)=atan(y(I)/x(I) ) - - - -.. - -The angles are calculated with 0.1 degree accuracy. For the (0,0) point, the angle is set to 0. - - -.. index:: Cbrt - -.. _Cbrt: - -Cbrt ----- - - - - -.. function:: Cbrt(value)-> float - - Calculates the cubic root - - - - - - - :param value: The input floating-point value - - :type value: float - - - -The function calculates the cubic root of the argument, and normally it is faster than -``pow(value,1./3)`` -. In addition, negative arguments are handled properly. Special values ( -:math:`\pm \infty` -, NaN) are not handled. - - -.. index:: ClearND - -.. _ClearND: - -ClearND -------- - - - - -.. function:: ClearND(arr,idx)-> None - - Clears a specific array element. - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx: Array of the element indices - - :type idx: sequence of int - - - -The function -:ref:`ClearND` -clears (sets to zero) a specific element of a dense array or deletes the element of a sparse array. If the sparse array element does not exists, the function does nothing. - - -.. index:: CloneImage - -.. _CloneImage: - -CloneImage ----------- - - - - -.. function:: CloneImage(image)-> copy - - Makes a full copy of an image, including the header, data, and ROI. - - - - - - - :param image: The original image - - :type image: :class:`IplImage` - - - -The returned -``IplImage*`` -points to the image copy. - - -.. index:: CloneMat - -.. _CloneMat: - -CloneMat --------- - - - - -.. function:: CloneMat(mat)-> copy - - Creates a full matrix copy. - - - - - - - :param mat: Matrix to be copied - - :type mat: :class:`CvMat` - - - -Creates a full copy of a matrix and returns a pointer to the copy. - - -.. index:: CloneMatND - -.. _CloneMatND: - -CloneMatND ----------- - - - - -.. function:: CloneMatND(mat)-> copy - - Creates full copy of a multi-dimensional array and returns a pointer to the copy. - - - - - - - :param mat: Input array - - :type mat: :class:`CvMatND` - - - - -.. index:: Cmp - -.. _Cmp: - -Cmp ---- - - - - -.. function:: Cmp(src1,src2,dst,cmpOp)-> None - - Performs per-element comparison of two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array. Both source arrays must have a single channel. - - :type src2: :class:`CvArr` - - - :param dst: The destination array, must have 8u or 8s type - - :type dst: :class:`CvArr` - - - :param cmpOp: The flag specifying the relation between the elements to be checked - - - * **CV_CMP_EQ** src1(I) "equal to" value - - - * **CV_CMP_GT** src1(I) "greater than" value - - - * **CV_CMP_GE** src1(I) "greater or equal" value - - - * **CV_CMP_LT** src1(I) "less than" value - - - * **CV_CMP_LE** src1(I) "less or equal" value - - - * **CV_CMP_NE** src1(I) "not equal" value - - - - :type cmpOp: int - - - -The function compares the corresponding elements of two arrays and fills the destination mask array: - - - - -:: - - - - dst(I)=src1(I) op src2(I), - - -.. - -``dst(I)`` -is set to 0xff (all -``1`` --bits) if the specific relation between the elements is true and 0 otherwise. All the arrays must have the same type, except the destination, and the same size (or ROI size) - - -.. index:: CmpS - -.. _CmpS: - -CmpS ----- - - - - -.. function:: CmpS(src,value,dst,cmpOp)-> None - - Performs per-element comparison of an array and a scalar. - - - - - - - :param src: The source array, must have a single channel - - :type src: :class:`CvArr` - - - :param value: The scalar value to compare each array element with - - :type value: float - - - :param dst: The destination array, must have 8u or 8s type - - :type dst: :class:`CvArr` - - - :param cmpOp: The flag specifying the relation between the elements to be checked - - - * **CV_CMP_EQ** src1(I) "equal to" value - - - * **CV_CMP_GT** src1(I) "greater than" value - - - * **CV_CMP_GE** src1(I) "greater or equal" value - - - * **CV_CMP_LT** src1(I) "less than" value - - - * **CV_CMP_LE** src1(I) "less or equal" value - - - * **CV_CMP_NE** src1(I) "not equal" value - - - - :type cmpOp: int - - - -The function compares the corresponding elements of an array and a scalar and fills the destination mask array: - - - - -:: - - - - dst(I)=src(I) op scalar - - -.. - -where -``op`` -is -:math:`=,\; >,\; \ge,\; <,\; \le\; or\; \ne` -. - -``dst(I)`` -is set to 0xff (all -``1`` --bits) if the specific relation between the elements is true and 0 otherwise. All the arrays must have the same size (or ROI size). - - -.. index:: Convert - -.. _Convert: - -Convert -------- - - - - -.. function:: Convert(src,dst)-> None - - Converts one array to another. - - - - - - - :param src: Source array - - :type src: :class:`CvArr` - - - :param dst: Destination array - - :type dst: :class:`CvArr` - - - -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. - -All the channels of multi-channel arrays are processed independently. - - -.. index:: ConvertScale - -.. _ConvertScale: - -ConvertScale ------------- - - - - -.. function:: ConvertScale(src,dst,scale=1.0,shift=0.0)-> None - - Converts one array to another with optional linear transformation. - - - - - - - :param src: Source array - - :type src: :class:`CvArr` - - - :param dst: Destination array - - :type dst: :class:`CvArr` - - - :param scale: Scale factor - - :type scale: float - - - :param shift: Value added to the scaled source array elements - - :type shift: float - - - -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: - - - -.. math:: - - \texttt{dst} (I) = \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...) - - -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. - -In the case of -``scale=1, shift=0`` -no prescaling is done. This is a specially -optimized case and it has the appropriate -:ref:`Convert` -name. If -source and destination array types have equal types, this is also a -special case that can be used to scale and shift a matrix or an image -and that is caled -:ref:`Scale` -. - - - -.. index:: ConvertScaleAbs - -.. _ConvertScaleAbs: - -ConvertScaleAbs ---------------- - - - - -.. function:: ConvertScaleAbs(src,dst,scale=1.0,shift=0.0)-> None - - Converts input array elements to another 8-bit unsigned integer with optional linear transformation. - - - - - - - :param src: Source array - - :type src: :class:`CvArr` - - - :param dst: Destination array (should have 8u depth) - - :type dst: :class:`CvArr` - - - :param scale: ScaleAbs factor - - :type scale: float - - - :param shift: Value added to the scaled source array elements - - :type shift: float - - - -The function is similar to -:ref:`ConvertScale` -, but it stores absolute values of the conversion results: - - - -.. math:: - - \texttt{dst} (I) = | \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...)| - - -The function supports only destination arrays of 8u (8-bit unsigned integers) type; for other types the function can be emulated by a combination of -:ref:`ConvertScale` -and -:ref:`Abs` -functions. - - -.. index:: CvtScaleAbs - -.. _CvtScaleAbs: - -CvtScaleAbs ------------ - - - - -.. function:: CvtScaleAbs(src,dst,scale=1.0,shift=0.0)-> None - - Converts input array elements to another 8-bit unsigned integer with optional linear transformation. - - - - - - - :param src: Source array - - - :param dst: Destination array (should have 8u depth) - - - :param scale: ScaleAbs factor - - - :param shift: Value added to the scaled source array elements - - - -The function is similar to -:ref:`ConvertScale` -, but it stores absolute values of the conversion results: - - - -.. math:: - - \texttt{dst} (I) = | \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...)| - - -The function supports only destination arrays of 8u (8-bit unsigned integers) type; for other types the function can be emulated by a combination of -:ref:`ConvertScale` -and -:ref:`Abs` -functions. - - -.. index:: Copy - -.. _Copy: - -Copy ----- - - - - -.. function:: Copy(src,dst,mask=NULL)-> None - - Copies one array to another. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function copies selected elements from an input array to an output array: - - - -.. math:: - - \texttt{dst} (I)= \texttt{src} (I) \quad \text{if} \quad \texttt{mask} (I) \ne 0. - - -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). - - -.. index:: CountNonZero - -.. _CountNonZero: - -CountNonZero ------------- - - - - -.. function:: CountNonZero(arr)-> int - - Counts non-zero array elements. - - - - - - - :param arr: The array must be a single-channel array or a multi-channel image with COI set - - :type arr: :class:`CvArr` - - - -The function returns the number of non-zero elements in arr: - - - -.. math:: - - \sum _I ( \texttt{arr} (I) \ne 0) - - -In the case of -``IplImage`` -both ROI and COI are supported. - - - -.. index:: CreateData - -.. _CreateData: - -CreateData ----------- - - - - -.. function:: CreateData(arr) -> None - - Allocates array data - - - - - - - :param arr: Array header - - :type arr: :class:`CvArr` - - - -The function allocates image, matrix or -multi-dimensional array data. Note that in the case of matrix types OpenCV -allocation functions are used and in the case of IplImage they are used -unless -``CV_TURN_ON_IPL_COMPATIBILITY`` -was called. In the -latter case IPL functions are used to allocate the data. - - -.. index:: CreateImage - -.. _CreateImage: - -CreateImage ------------ - - - - -.. function:: CreateImage(size, depth, channels)->image - - Creates an image header and allocates the image data. - - - - - - - :param size: Image width and height - - :type size: :class:`CvSize` - - - :param depth: Bit depth of image elements. See :ref:`IplImage` for valid depths. - - :type depth: int - - - :param channels: Number of channels per pixel. See :ref:`IplImage` for details. This function only creates images with interleaved channels. - - :type channels: int - - - - -.. index:: CreateImageHeader - -.. _CreateImageHeader: - -CreateImageHeader ------------------ - - - - -.. function:: CreateImageHeader(size, depth, channels) -> image - - Creates an image header but does not allocate the image data. - - - - - - - :param size: Image width and height - - :type size: :class:`CvSize` - - - :param depth: Image depth (see :ref:`CreateImage` ) - - :type depth: int - - - :param channels: Number of channels (see :ref:`CreateImage` ) - - :type channels: int - - - - -.. index:: CreateMat - -.. _CreateMat: - -CreateMat ---------- - - - - -.. function:: CreateMat(rows, cols, type) -> mat - - Creates a matrix header and allocates the matrix data. - - - - - - - :param rows: Number of rows in the matrix - - :type rows: int - - - :param cols: Number of columns in the matrix - - :type cols: int - - - :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. - - :type type: int - - - - -.. index:: CreateMatHeader - -.. _CreateMatHeader: - -CreateMatHeader ---------------- - - - - -.. function:: CreateMatHeader(rows, cols, type) -> mat - - Creates a matrix header but does not allocate the matrix data. - - - - - - - :param rows: Number of rows in the matrix - - :type rows: int - - - :param cols: Number of columns in the matrix - - :type cols: int - - - :param type: Type of the matrix elements, see :ref:`CreateMat` - - :type type: int - - - -The function allocates a new matrix header and returns a pointer to it. The matrix data can then be allocated using -:ref:`CreateData` -or set explicitly to user-allocated data via -:ref:`SetData` -. - - -.. index:: CreateMatND - -.. _CreateMatND: - -CreateMatND ------------ - - - - -.. function:: CreateMatND(dims, type) -> None - - Creates the header and allocates the data for a multi-dimensional dense array. - - - - - - - :param dims: List or tuple of array dimensions, up to 32 in length. - - :type dims: sequence of int - - - :param type: Type of array elements, see :ref:`CreateMat` . - - :type type: int - - - -This is a short form for: - - -.. index:: CreateMatNDHeader - -.. _CreateMatNDHeader: - -CreateMatNDHeader ------------------ - - - - -.. function:: CreateMatNDHeader(dims, type) -> None - - Creates a new matrix header but does not allocate the matrix data. - - - - - - - :param dims: List or tuple of array dimensions, up to 32 in length. - - :type dims: sequence of int - - - :param type: Type of array elements, see :ref:`CreateMat` - - :type type: int - - - -The function allocates a header for a multi-dimensional dense array. The array data can further be allocated using -:ref:`CreateData` -or set explicitly to user-allocated data via -:ref:`SetData` -. - - -.. index:: CrossProduct - -.. _CrossProduct: - -CrossProduct ------------- - - - - -.. function:: CrossProduct(src1,src2,dst)-> None - - Calculates the cross product of two 3D vectors. - - - - - - - :param src1: The first source vector - - :type src1: :class:`CvArr` - - - :param src2: The second source vector - - :type src2: :class:`CvArr` - - - :param dst: The destination vector - - :type dst: :class:`CvArr` - - - -The function calculates the cross product of two 3D vectors: - - - -.. math:: - - \texttt{dst} = \texttt{src1} \times \texttt{src2} - - -or: - - -.. math:: - - \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} - - - -CvtPixToPlane -------------- - - -Synonym for -:ref:`Split` -. - - -.. index:: DCT - -.. _DCT: - -DCT ---- - - - - -.. function:: DCT(src,dst,flags)-> None - - Performs a forward or inverse Discrete Cosine transform of a 1D or 2D floating-point array. - - - - - - - :param src: Source array, real 1D or 2D array - - :type src: :class:`CvArr` - - - :param dst: Destination array of the same size and same type as the source - - :type dst: :class:`CvArr` - - - :param flags: Transformation flags, a combination of the following values - - * **CV_DXT_FORWARD** do a forward 1D or 2D transform. - - * **CV_DXT_INVERSE** do an inverse 1D or 2D transform. - - * **CV_DXT_ROWS** do a forward or inverse transform of every individual row of the input matrix. This flag allows user to transform multiple vectors simultaneously and can be used to decrease the overhead (which is sometimes several times larger than the processing itself), to do 3D and higher-dimensional transforms and so forth. - - - - :type flags: int - - - -The function performs a forward or inverse transform of a 1D or 2D floating-point array: - -Forward Cosine transform of 1D vector of -:math:`N` -elements: - - -.. math:: - - Y = C^{(N)} \cdot X - - -where - - -.. math:: - - C^{(N)}_{jk}= \sqrt{\alpha_j/N} \cos \left ( \frac{\pi(2k+1)j}{2N} \right ) - - -and -:math:`\alpha_0=1` -, -:math:`\alpha_j=2` -for -:math:`j > 0` -. - -Inverse Cosine transform of 1D vector of N elements: - - -.. math:: - - X = \left (C^{(N)} \right )^{-1} \cdot Y = \left (C^{(N)} \right )^T \cdot Y - - -(since -:math:`C^{(N)}` -is orthogonal matrix, -:math:`C^{(N)} \cdot \left(C^{(N)}\right)^T = I` -) - -Forward Cosine transform of 2D -:math:`M \times N` -matrix: - - -.. math:: - - Y = C^{(N)} \cdot X \cdot \left (C^{(N)} \right )^T - - -Inverse Cosine transform of 2D vector of -:math:`M \times N` -elements: - - -.. math:: - - X = \left (C^{(N)} \right )^T \cdot X \cdot C^{(N)} - - - -.. index:: DFT - -.. _DFT: - -DFT ---- - - - - -.. function:: DFT(src,dst,flags,nonzeroRows=0)-> None - - Performs a forward or inverse Discrete Fourier transform of a 1D or 2D floating-point array. - - - - - - - :param src: Source array, real or complex - - :type src: :class:`CvArr` - - - :param dst: Destination array of the same size and same type as the source - - :type dst: :class:`CvArr` - - - :param flags: Transformation flags, a combination of the following values - - * **CV_DXT_FORWARD** do a forward 1D or 2D transform. The result is not scaled. - - * **CV_DXT_INVERSE** do an inverse 1D or 2D transform. The result is not scaled. ``CV_DXT_FORWARD`` and ``CV_DXT_INVERSE`` are mutually exclusive, of course. - - * **CV_DXT_SCALE** scale the result: divide it by the number of array elements. Usually, it is combined with ``CV_DXT_INVERSE`` , and one may use a shortcut ``CV_DXT_INV_SCALE`` . - - * **CV_DXT_ROWS** do a forward or inverse transform of every individual row of the input matrix. This flag allows the user to transform multiple vectors simultaneously and can be used to decrease the overhead (which is sometimes several times larger than the processing itself), to do 3D and higher-dimensional transforms and so forth. - - * **CV_DXT_INVERSE_SCALE** same as ``CV_DXT_INVERSE + CV_DXT_SCALE`` - - - - :type flags: int - - - :param nonzeroRows: Number of nonzero rows in the source array - (in the case of a forward 2d transform), or a number of rows of interest in - the destination array (in the case of an inverse 2d transform). If the value - is negative, zero, or greater than the total number of rows, it is - ignored. The parameter can be used to speed up 2d convolution/correlation - when computing via DFT. See the example below. - - :type nonzeroRows: int - - - -The function performs a forward or inverse transform of a 1D or 2D floating-point array: - - -Forward Fourier transform of 1D vector of N elements: - - -.. math:: - - y = F^{(N)} \cdot x, where F^{(N)}_{jk}=exp(-i \cdot 2 \pi \cdot j \cdot k/N) - - -, - - -.. math:: - - i=sqrt(-1) - - -Inverse Fourier transform of 1D vector of N elements: - - -.. math:: - - x'= (F^{(N)})^{-1} \cdot y = conj(F^(N)) \cdot y - x = (1/N) \cdot x - - -Forward Fourier transform of 2D vector of M -:math:`\times` -N elements: - - -.. math:: - - Y = F^{(M)} \cdot X \cdot F^{(N)} - - -Inverse Fourier transform of 2D vector of M -:math:`\times` -N elements: - - -.. math:: - - X'= conj(F^{(M)}) \cdot Y \cdot conj(F^{(N)}) - X = (1/(M \cdot N)) \cdot X' - - -In the case of real (single-channel) data, the packed format, borrowed from IPL, is used to represent the result of a forward Fourier transform or input for an inverse Fourier transform: - - - -.. math:: - - \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} - - -Note: the last column is present if -``N`` -is even, the last row is present if -``M`` -is even. -In the case of 1D real transform the result looks like the first row of the above matrix. - -Here is the example of how to compute 2D convolution using DFT. - - -.. index:: Det - -.. _Det: - -Det ---- - - - - -.. function:: Det(mat)-> double - - Returns the determinant of a matrix. - - - - - - - :param mat: The source matrix - - :type mat: :class:`CvArr` - - - -The function returns the determinant of the square matrix -``mat`` -. The direct method is used for small matrices and Gaussian elimination is used for larger matrices. For symmetric positive-determined matrices, it is also possible to run -:ref:`SVD` -with -:math:`U = V = 0` -and then calculate the determinant as a product of the diagonal elements of -:math:`W` -. - - -.. index:: Div - -.. _Div: - -Div ---- - - - - -.. function:: Div(src1,src2,dst,scale)-> None - - Performs per-element division of two arrays. - - - - - - - :param src1: The first source array. If the pointer is NULL, the array is assumed to be all 1's. - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param scale: Optional scale factor - - :type scale: float - - - -The function divides one array by another: - - - -.. math:: - - \texttt{dst} (I)= \fork{\texttt{scale} \cdot \texttt{src1}(I)/\texttt{src2}(I)}{if \texttt{src1} is not \texttt{NULL}}{\texttt{scale}/\texttt{src2}(I)}{otherwise} - - -All the arrays must have the same type and the same size (or ROI size). - - - -.. index:: DotProduct - -.. _DotProduct: - -DotProduct ----------- - - - - -.. function:: DotProduct(src1,src2)-> double - - Calculates the dot product of two arrays in Euclidian metrics. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - -The function calculates and returns the Euclidean dot product of two arrays. - - - -.. math:: - - src1 \bullet src2 = \sum _I ( \texttt{src1} (I) \texttt{src2} (I)) - - -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 -:math:`||\texttt{a}||^2` -. -The function can process multi-dimensional arrays, row by row, layer by layer, and so on. - - -.. index:: EigenVV - -.. _EigenVV: - -EigenVV -------- - - - - -.. function:: EigenVV(mat,evects,evals,eps,lowindex,highindex)-> None - - Computes eigenvalues and eigenvectors of a symmetric matrix. - - - - - - - :param mat: The input symmetric square matrix, modified during the processing - - :type mat: :class:`CvArr` - - - :param evects: The output matrix of eigenvectors, stored as subsequent rows - - :type evects: :class:`CvArr` - - - :param evals: The output vector of eigenvalues, stored in the descending order (order of eigenvalues and eigenvectors is syncronized, of course) - - :type evals: :class:`CvArr` - - - :param eps: Accuracy of diagonalization. Typically, ``DBL_EPSILON`` (about :math:`10^{-15}` ) works well. - THIS PARAMETER IS CURRENTLY IGNORED. - - :type eps: float - - - :param lowindex: Optional index of largest eigenvalue/-vector to calculate. - (See below.) - - :type lowindex: int - - - :param highindex: Optional index of smallest eigenvalue/-vector to calculate. - (See below.) - - :type highindex: int - - - -The function computes the eigenvalues and eigenvectors of matrix -``A`` -: - - - - -:: - - - - mat*evects(i,:)' = evals(i)*evects(i,:)' (in MATLAB notation) - - -.. - -If either low- or highindex is supplied the other is required, too. -Indexing is 0-based. Example: To calculate the largest eigenvector/-value set -``lowindex=highindex=0`` -. To calculate all the eigenvalues, leave -``lowindex=highindex=-1`` -. -For legacy reasons this function always returns a square matrix the same size -as the source matrix with eigenvectors and a vector the length of the source -matrix with eigenvalues. The selected eigenvectors/-values are always in the -first highindex - lowindex + 1 rows. - -The contents of matrix -``A`` -is destroyed by the function. - -Currently the function is slower than -:ref:`SVD` -yet less accurate, -so if -``A`` -is known to be positively-defined (for example, it -is a covariance matrix)it is recommended to use -:ref:`SVD` -to find -eigenvalues and eigenvectors of -``A`` -, especially if eigenvectors -are not required. - - -.. index:: Exp - -.. _Exp: - -Exp ---- - - - - -.. function:: Exp(src,dst)-> None - - Calculates the exponent of every array element. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param dst: The destination array, it should have ``double`` type or the same type as the source - - :type dst: :class:`CvArr` - - - -The function calculates the exponent of every element of the input array: - - - -.. math:: - - \texttt{dst} [I] = e^{ \texttt{src} (I)} - - -The maximum relative error is about -:math:`7 \times 10^{-6}` -. Currently, the function converts denormalized values to zeros on output. - - -.. index:: FastArctan - -.. _FastArctan: - -FastArctan ----------- - - - - -.. function:: FastArctan(y,x)-> float - - Calculates the angle of a 2D vector. - - - - - - - :param x: x-coordinate of 2D vector - - :type x: float - - - :param y: y-coordinate of 2D vector - - :type y: float - - - -The function calculates the full-range angle of an input 2D vector. The angle is -measured in degrees and varies from 0 degrees to 360 degrees. The accuracy is about 0.1 degrees. - - -.. index:: Flip - -.. _Flip: - -Flip ----- - - - - -.. function:: Flip(src,dst=NULL,flipMode=0)-> None - - Flip a 2D array around vertical, horizontal or both axes. - - - - - - - :param src: Source array - - :type src: :class:`CvArr` - - - :param dst: Destination array. - If :math:`\texttt{dst} = \texttt{NULL}` the flipping is done in place. - - :type dst: :class:`CvArr` - - - :param flipMode: Specifies how to flip the array: - 0 means flipping around the x-axis, positive (e.g., 1) means flipping around y-axis, and negative (e.g., -1) means flipping around both axes. See also the discussion below for the formulas: - - :type flipMode: int - - - -The function flips the array in one of three different ways (row and column indices are 0-based): - - - -.. math:: - - dst(i,j) = \forkthree{\texttt{src}(rows(\texttt{src})-i-1,j)}{if $\texttt{flipMode} = 0$}{\texttt{src}(i,cols(\texttt{src})-j-1)}{if $\texttt{flipMode} > 0$}{\texttt{src}(rows(\texttt{src})-i-1,cols(\texttt{src})-j-1)}{if $\texttt{flipMode} < 0$} - - -The example scenarios of function use are: - - - - -* - vertical flipping of the image (flipMode = 0) to switch between top-left and bottom-left image origin, which is a typical operation in video processing under Win32 systems. - - - -* - horizontal flipping of the image with subsequent horizontal shift and absolute difference calculation to check for a vertical-axis symmetry (flipMode - :math:`>` - 0) - - - -* - simultaneous horizontal and vertical flipping of the image with subsequent shift and absolute difference calculation to check for a central symmetry (flipMode - :math:`<` - 0) - - - -* - reversing the order of 1d point arrays (flipMode > 0) - - - -.. index:: fromarray - -.. _fromarray: - -fromarray ---------- - - - - -.. function:: fromarray(object, allowND = False) -> CvMat - - Create a CvMat from an object that supports the array interface. - - - - - - - :param object: Any object that supports the array interface - - - :param allowND: If true, will return a CvMatND - - - -If the object supports the -`array interface `_ -, -return a -:ref:`CvMat` -( -``allowND = False`` -) or -:ref:`CvMatND` -( -``allowND = True`` -). - -If -``allowND = False`` -, then the object's array must be either 2D or 3D. If it is 2D, then the returned CvMat has a single channel. If it is 3D, then the returned CvMat will have N channels, where N is the last dimension of the array. In this case, N cannot be greater than OpenCV's channel limit, -``CV_CN_MAX`` -. - -If -``allowND = True`` -, then -``fromarray`` -returns a single-channel -:ref:`CvMatND` -with the same shape as the original array. - -For example, -`NumPy `_ -arrays support the array interface, so can be converted to OpenCV objects: - - - - -.. doctest:: - - - - >>> import cv, numpy - >>> a = numpy.ones((480, 640)) - >>> mat = cv.fromarray(a) - >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) - (480, 640) 1 - >>> a = numpy.ones((480, 640, 3)) - >>> mat = cv.fromarray(a) - >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) - (480, 640) 3 - >>> a = numpy.ones((480, 640, 3)) - >>> mat = cv.fromarray(a, allowND = True) - >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) - (480, 640, 3) 1 - - -.. - - -.. index:: GEMM - -.. _GEMM: - -GEMM ----- - - - - -.. function:: GEMM(src1,src2,alphs,src3,beta,dst,tABC=0)-> None - - Performs generalized matrix multiplication. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param src3: The third source array (shift). Can be NULL, if there is no shift. - - :type src3: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param tABC: The operation flags that can be 0 or a combination of the following values - - * **CV_GEMM_A_T** transpose src1 - - * **CV_GEMM_B_T** transpose src2 - - * **CV_GEMM_C_T** transpose src3 - - - - For example, ``CV_GEMM_A_T+CV_GEMM_C_T`` corresponds to - - .. math:: - - \texttt{alpha} \, \texttt{src1} ^T \, \texttt{src2} + \texttt{beta} \, \texttt{src3} ^T - - - - :type tABC: int - - - -The function performs generalized matrix multiplication: - - - -.. math:: - - \texttt{dst} = \texttt{alpha} \, op( \texttt{src1} ) \, op( \texttt{src2} ) + \texttt{beta} \, op( \texttt{src3} ) \quad \text{where $op(X)$ is $X$ or $X^T$} - - -All the matrices should have the same data type and coordinated sizes. Real or complex floating-point matrices are supported. - - -.. index:: Get1D - -.. _Get1D: - -Get1D ------ - - - - -.. function:: Get1D(arr, idx) -> scalar - - Return a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx: Zero-based element index - - :type idx: int - - - -Return a specific array element. Array must have dimension 3. - - -.. index:: Get2D - -.. _Get2D: - -Get2D ------ - - - - -.. function:: Get2D(arr, idx0, idx1) -> scalar - - Return a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx0: Zero-based element row index - - :type idx0: int - - - :param idx1: Zero-based element column index - - :type idx1: int - - - -Return a specific array element. Array must have dimension 2. - - -.. index:: Get3D - -.. _Get3D: - -Get3D ------ - - - - -.. function:: Get3D(arr, idx0, idx1, idx2) -> scalar - - Return a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx0: Zero-based element index - - :type idx0: int - - - :param idx1: Zero-based element index - - :type idx1: int - - - :param idx2: Zero-based element index - - :type idx2: int - - - -Return a specific array element. Array must have dimension 3. - - -.. index:: GetND - -.. _GetND: - -GetND ------ - - - - -.. function:: GetND(arr, indices) -> scalar - - Return a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param indices: List of zero-based element indices - - :type indices: sequence of int - - - -Return a specific array element. The length of array indices must be the same as the dimension of the array. - - -.. index:: GetCol - -.. _GetCol: - -GetCol ------- - - - - -.. function:: GetCol(arr,col)-> submat - - Returns array column. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param col: Zero-based index of the selected column - - :type col: int - - - :param submat: resulting single-column array - - :type submat: :class:`CvMat` - - - -The function -``GetCol`` -returns a single column from the input array. - - -.. index:: GetCols - -.. _GetCols: - -GetCols -------- - - - - -.. function:: GetCols(arr,startCol,endCol)-> submat - - Returns array column span. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param startCol: Zero-based index of the starting column (inclusive) of the span - - :type startCol: int - - - :param endCol: Zero-based index of the ending column (exclusive) of the span - - :type endCol: int - - - :param submat: resulting multi-column array - - :type submat: :class:`CvMat` - - - -The function -``GetCols`` -returns a column span from the input array. - - -.. index:: GetDiag - -.. _GetDiag: - -GetDiag -------- - - - - -.. function:: GetDiag(arr,diag=0)-> submat - - Returns one of array diagonals. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param submat: Pointer to the resulting sub-array header - - :type submat: :class:`CvMat` - - - :param diag: Array diagonal. Zero corresponds to the main diagonal, -1 corresponds to the diagonal above the main , 1 corresponds to the diagonal below the main, and so forth. - - :type diag: int - - - -The function returns the header, corresponding to a specified diagonal of the input array. - - -.. index:: GetDims - -.. _GetDims: - -GetDims -------- - - - - -.. function:: GetDims(arr)-> list - - Returns list of array dimensions - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - -The function returns a list of array dimensions. -In the case of -``IplImage`` -or -:ref:`CvMat` -it always -returns a list of length 2. - -.. index:: GetElemType - -.. _GetElemType: - -GetElemType ------------ - - - - -.. function:: GetElemType(arr)-> int - - Returns type of array elements. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - -The function returns type of the array elements -as described in -:ref:`CreateMat` -discussion: -``CV_8UC1`` -... -``CV_64FC4`` -. - - - -.. index:: GetImage - -.. _GetImage: - -GetImage --------- - - - - -.. function:: GetImage(arr) -> iplimage - - Returns image header for arbitrary array. - - - - - - - :param arr: Input array - - :type arr: :class:`CvMat` - - - -The function returns the image header for the input array -that can be a matrix - -:ref:`CvMat` -, or an image - -``IplImage*`` -. In -the case of an image the function simply returns the input pointer. In the -case of -:ref:`CvMat` -it initializes an -``imageHeader`` -structure -with the parameters of the input matrix. Note that if we transform -``IplImage`` -to -:ref:`CvMat` -and then transform CvMat back to -IplImage, we can get different headers if the ROI is set, and thus some -IPL functions that calculate image stride from its width and align may -fail on the resultant image. - - -.. index:: GetImageCOI - -.. _GetImageCOI: - -GetImageCOI ------------ - - - - -.. function:: GetImageCOI(image)-> channel - - Returns the index of the channel of interest. - - - - - - - :param image: A pointer to the image header - - :type image: :class:`IplImage` - - - -Returns the channel of interest of in an IplImage. Returned values correspond to the -``coi`` -in -:ref:`SetImageCOI` -. - - -.. index:: GetImageROI - -.. _GetImageROI: - -GetImageROI ------------ - - - - -.. function:: GetImageROI(image)-> CvRect - - Returns the image ROI. - - - - - - - :param image: A pointer to the image header - - :type image: :class:`IplImage` - - - -If there is no ROI set, -``cvRect(0,0,image->width,image->height)`` -is returned. - - -.. index:: GetMat - -.. _GetMat: - -GetMat ------- - - - - -.. function:: GetMat(arr, allowND=0) -> cvmat - - Returns matrix header for arbitrary array. - - - - - - - :param arr: Input array - - :type arr: :class:`IplImage` - - - :param allowND: If non-zero, the function accepts multi-dimensional dense arrays (CvMatND*) and returns 2D (if CvMatND has two dimensions) or 1D matrix (when CvMatND has 1 dimension or more than 2 dimensions). The array must be continuous. - - :type allowND: int - - - -The function returns a matrix header for the input array that can be a matrix - - -:ref:`CvMat` -, an image - -``IplImage`` -or a multi-dimensional dense array - -:ref:`CvMatND` -(latter case is allowed only if -``allowND != 0`` -) . In the case of matrix the function simply returns the input pointer. In the case of -``IplImage*`` -or -:ref:`CvMatND` -it initializes the -``header`` -structure with parameters of the current image ROI and returns the pointer to this temporary structure. Because COI is not supported by -:ref:`CvMat` -, it is returned separately. - -The function provides an easy way to handle both types of arrays - -``IplImage`` -and -:ref:`CvMat` -- using the same code. Reverse transform from -:ref:`CvMat` -to -``IplImage`` -can be done using the -:ref:`GetImage` -function. - -Input array must have underlying data allocated or attached, otherwise the function fails. - -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. It enables per-plane processing of multi-channel images with planar data layout using OpenCV functions. - - -.. index:: GetOptimalDFTSize - -.. _GetOptimalDFTSize: - -GetOptimalDFTSize ------------------ - - - - -.. function:: GetOptimalDFTSize(size0)-> int - - Returns optimal DFT size for a given vector size. - - - - - - - :param size0: Vector size - - :type size0: int - - - -The function returns the minimum number -``N`` -that is greater than or equal to -``size0`` -, such that the DFT -of a vector of size -``N`` -can be computed fast. In the current -implementation -:math:`N=2^p \times 3^q \times 5^r` -, for some -:math:`p` -, -:math:`q` -, -:math:`r` -. - -The function returns a negative number if -``size0`` -is too large -(very close to -``INT_MAX`` -) - - - -.. index:: GetReal1D - -.. _GetReal1D: - -GetReal1D ---------- - - - - -.. function:: GetReal1D(arr, idx0)->float - - Return a specific element of single-channel 1D array. - - - - - - - :param arr: Input array. Must have a single channel. - - :type arr: :class:`CvArr` - - - :param idx0: The first zero-based component of the element index - - :type idx0: int - - - -Returns a specific element of a single-channel array. If the array has -multiple channels, a runtime error is raised. Note that -:ref:`Get` -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 return 0 if the requested node does not exist (no new node is created by the functions). - - -.. index:: GetReal2D - -.. _GetReal2D: - -GetReal2D ---------- - - - - -.. function:: GetReal2D(arr, idx0, idx1)->float - - Return a specific element of single-channel 2D array. - - - - - - - :param arr: Input array. Must have a single channel. - - :type arr: :class:`CvArr` - - - :param idx0: The first zero-based component of the element index - - :type idx0: int - - - :param idx1: The second zero-based component of the element index - - :type idx1: int - - - -Returns a specific element of a single-channel array. If the array has -multiple channels, a runtime error is raised. Note that -:ref:`Get` -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 return 0 if the requested node does not exist (no new node is created by the functions). - - -.. index:: GetReal3D - -.. _GetReal3D: - -GetReal3D ---------- - - - - -.. function:: GetReal3D(arr, idx0, idx1, idx2)->float - - Return a specific element of single-channel array. - - - - - - - :param arr: Input array. Must have a single channel. - - :type arr: :class:`CvArr` - - - :param idx0: The first zero-based component of the element index - - :type idx0: int - - - :param idx1: The second zero-based component of the element index - - :type idx1: int - - - :param idx2: The third zero-based component of the element index - - :type idx2: int - - - -Returns a specific element of a single-channel array. If the array has -multiple channels, a runtime error is raised. Note that -:ref:`Get` -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 return 0 if the requested node does not exist (no new node is created by the functions). - - -.. index:: GetRealND - -.. _GetRealND: - -GetRealND ---------- - - - - -.. function:: GetRealND(arr, idx)->float - - Return a specific element of single-channel array. - - - - - - - :param arr: Input array. Must have a single channel. - - :type arr: :class:`CvArr` - - - :param idx: Array of the element indices - - :type idx: sequence of int - - - -Returns a specific element of a single-channel array. If the array has -multiple channels, a runtime error is raised. Note that -:ref:`Get` -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 return 0 if the requested node does not exist (no new node is created by the functions). - - - -.. index:: GetRow - -.. _GetRow: - -GetRow ------- - - - - -.. function:: GetRow(arr,row)-> submat - - Returns array row. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param row: Zero-based index of the selected row - - :type row: int - - - :param submat: resulting single-row array - - :type submat: :class:`CvMat` - - - -The function -``GetRow`` -returns a single row from the input array. - - -.. index:: GetRows - -.. _GetRows: - -GetRows -------- - - - - -.. function:: GetRows(arr,startRow,endRow,deltaRow=1)-> submat - - Returns array row span. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param startRow: Zero-based index of the starting row (inclusive) of the span - - :type startRow: int - - - :param endRow: Zero-based index of the ending row (exclusive) of the span - - :type endRow: int - - - :param deltaRow: Index step in the row span. - - :type deltaRow: int - - - :param submat: resulting multi-row array - - :type submat: :class:`CvMat` - - - -The function -``GetRows`` -returns a row span from the input array. - - -.. index:: GetSize - -.. _GetSize: - -GetSize -------- - - - - -.. function:: GetSize(arr)-> CvSize - - Returns size of matrix or image ROI. - - - - - - - :param arr: array header - - :type arr: :class:`CvArr` - - - -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. - - - -.. index:: GetSubRect - -.. _GetSubRect: - -GetSubRect ----------- - - - - -.. function:: GetSubRect(arr, rect) -> cvmat - - Returns matrix header corresponding to the rectangular sub-array of input image or matrix. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param rect: Zero-based coordinates of the rectangle of interest - - :type rect: :class:`CvRect` - - - -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. - - -.. index:: InRange - -.. _InRange: - -InRange -------- - - - - -.. function:: InRange(src,lower,upper,dst)-> None - - Checks that array elements lie between the elements of two other arrays. - - - - - - - :param src: The first source array - - :type src: :class:`CvArr` - - - :param lower: The inclusive lower boundary array - - :type lower: :class:`CvArr` - - - :param upper: The exclusive upper boundary array - - :type upper: :class:`CvArr` - - - :param dst: The destination array, must have 8u or 8s type - - :type dst: :class:`CvArr` - - - -The function does the range check for every element of the input array: - - - -.. math:: - - \texttt{dst} (I)= \texttt{lower} (I)_0 <= \texttt{src} (I)_0 < \texttt{upper} (I)_0 - - -For single-channel arrays, - - - -.. math:: - - \texttt{dst} (I)= \texttt{lower} (I)_0 <= \texttt{src} (I)_0 < \texttt{upper} (I)_0 \land \texttt{lower} (I)_1 <= \texttt{src} (I)_1 < \texttt{upper} (I)_1 - - -For two-channel arrays and so forth, - -dst(I) is set to 0xff (all -``1`` --bits) if src(I) is within the range and 0 otherwise. All the arrays must have the same type, except the destination, and the same size (or ROI size). - - - -.. index:: InRangeS - -.. _InRangeS: - -InRangeS --------- - - - - -.. function:: InRangeS(src,lower,upper,dst)-> None - - Checks that array elements lie between two scalars. - - - - - - - :param src: The first source array - - :type src: :class:`CvArr` - - - :param lower: The inclusive lower boundary - - :type lower: :class:`CvScalar` - - - :param upper: The exclusive upper boundary - - :type upper: :class:`CvScalar` - - - :param dst: The destination array, must have 8u or 8s type - - :type dst: :class:`CvArr` - - - -The function does the range check for every element of the input array: - - - -.. math:: - - \texttt{dst} (I)= \texttt{lower} _0 <= \texttt{src} (I)_0 < \texttt{upper} _0 - - -For single-channel arrays, - - - -.. math:: - - \texttt{dst} (I)= \texttt{lower} _0 <= \texttt{src} (I)_0 < \texttt{upper} _0 \land \texttt{lower} _1 <= \texttt{src} (I)_1 < \texttt{upper} _1 - - -For two-channel arrays nd so forth, - -'dst(I)' is set to 0xff (all -``1`` --bits) if 'src(I)' is within the range and 0 otherwise. All the arrays must have the same size (or ROI size). - - -.. index:: InvSqrt - -.. _InvSqrt: - -InvSqrt -------- - - - - -.. function:: InvSqrt(value)-> float - - Calculates the inverse square root. - - - - - - - :param value: The input floating-point value - - :type value: float - - - -The function calculates the inverse square root of the argument, and normally it is faster than -``1./sqrt(value)`` -. If the argument is zero or negative, the result is not determined. Special values ( -:math:`\pm \infty` -, NaN) are not handled. - - -.. index:: Inv - -.. _Inv: - -Inv ---- - - - - -:ref:`Invert` - -.. index:: - -.. _: - - - - - - - -.. function:: Invert(src,dst,method=CV_LU)-> double - - Finds the inverse or pseudo-inverse of a matrix. - - - - - - - :param src: The source matrix - - - :param dst: The destination matrix - - - :param method: Inversion method - - - * **CV_LU** Gaussian elimination with optimal pivot element chosen - - - * **CV_SVD** Singular value decomposition (SVD) method - - - * **CV_SVD_SYM** SVD method for a symmetric positively-defined matrix - - - - - -The function inverts matrix -``src1`` -and stores the result in -``src2`` -. - -In the case of -``LU`` -method, the function returns the -``src1`` -determinant (src1 must be square). If it is 0, the matrix is not inverted and -``src2`` -is filled with zeros. - -In the case of -``SVD`` -methods, the function returns the inversed condition of -``src1`` -(ratio of the smallest singular value to the largest singular value) and 0 if -``src1`` -is all zeros. The SVD methods calculate a pseudo-inverse matrix if -``src1`` -is singular. - - - -.. index:: IsInf - -.. _IsInf: - -IsInf ------ - - - - -.. function:: IsInf(value)-> int - - Determines if the argument is Infinity. - - - - - - - :param value: The input floating-point value - - :type value: float - - - -The function returns 1 if the argument is -:math:`\pm \infty` -(as defined by IEEE754 standard), 0 otherwise. - - -.. index:: IsNaN - -.. _IsNaN: - -IsNaN ------ - - - - -.. function:: IsNaN(value)-> int - - Determines if the argument is Not A Number. - - - - - - - :param value: The input floating-point value - - :type value: float - - - -The function returns 1 if the argument is Not A Number (as defined by IEEE754 standard), 0 otherwise. - - - -.. index:: LUT - -.. _LUT: - -LUT ---- - - - - -.. function:: LUT(src,dst,lut)-> None - - Performs a look-up table transform of an array. - - - - - - - :param src: Source array of 8-bit elements - - :type src: :class:`CvArr` - - - :param dst: Destination array of a given depth and of the same number of channels as the source array - - :type dst: :class:`CvArr` - - - :param lut: Look-up table of 256 elements; should have the same depth as the destination array. In the case of multi-channel source and destination arrays, 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 the source/destination array. - - :type lut: :class:`CvArr` - - - -The function fills the destination array with values from the look-up table. Indices of the entries are taken from the source array. That is, the function processes each element of -``src`` -as follows: - - - -.. math:: - - \texttt{dst} _i \leftarrow \texttt{lut} _{ \texttt{src} _i + d} - - -where - - - -.. math:: - - d = \fork{0}{if \texttt{src} has depth \texttt{CV\_8U}}{128}{if \texttt{src} has depth \texttt{CV\_8S}} - - - -.. index:: Log - -.. _Log: - -Log ---- - - - - -.. function:: Log(src,dst)-> None - - Calculates the natural logarithm of every array element's absolute value. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param dst: The destination array, it should have ``double`` type or the same type as the source - - :type dst: :class:`CvArr` - - - -The function calculates the natural logarithm of the absolute value of every element of the input array: - - - -.. math:: - - \texttt{dst} [I] = \fork{\log{|\texttt{src}(I)}}{if $\texttt{src}[I] \ne 0$ }{\texttt{C}}{otherwise} - - -Where -``C`` -is a large negative number (about -700 in the current implementation). - - -.. index:: Mahalanobis - -.. _Mahalanobis: - -Mahalanobis ------------ - - - - -.. function:: Mahalonobis(vec1,vec2,mat)-> None - - Calculates the Mahalanobis distance between two vectors. - - - - - - - :param vec1: The first 1D source vector - - - :param vec2: The second 1D source vector - - - :param mat: The inverse covariance matrix - - - -The function calculates and returns the weighted distance between two vectors: - - - -.. math:: - - 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)})} } - - -The covariance matrix may be calculated using the -:ref:`CalcCovarMatrix` -function and further inverted using the -:ref:`Invert` -function (CV -_ -SVD method is the prefered one because the matrix might be singular). - - - -.. index:: Max - -.. _Max: - -Max ---- - - - - -.. function:: Max(src1,src2,dst)-> None - - Finds per-element maximum of two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - -The function calculates per-element maximum of two arrays: - - - -.. math:: - - \texttt{dst} (I)= \max ( \texttt{src1} (I), \texttt{src2} (I)) - - -All the arrays must have a single channel, the same data type and the same size (or ROI size). - - - -.. index:: MaxS - -.. _MaxS: - -MaxS ----- - - - - -.. function:: MaxS(src,value,dst)-> None - - Finds per-element maximum of array and scalar. - - - - - - - :param src: The first source array - - :type src: :class:`CvArr` - - - :param value: The scalar value - - :type value: float - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - -The function calculates per-element maximum of array and scalar: - - - -.. math:: - - \texttt{dst} (I)= \max ( \texttt{src} (I), \texttt{value} ) - - -All the arrays must have a single channel, the same data type and the same size (or ROI size). - - - -.. index:: Merge - -.. _Merge: - -Merge ------ - - - - -.. function:: Merge(src0,src1,src2,src3,dst)-> None - - Composes a multi-channel array from several single-channel arrays or inserts a single channel into the array. - - - - - - - :param src0: Input channel 0 - - :type src0: :class:`CvArr` - - - :param src1: Input channel 1 - - :type src1: :class:`CvArr` - - - :param src2: Input channel 2 - - :type src2: :class:`CvArr` - - - :param src3: Input channel 3 - - :type src3: :class:`CvArr` - - - :param dst: Destination array - - :type dst: :class:`CvArr` - - - -The function is the opposite to -:ref:`Split` -. If the destination array has N channels then if the first N input channels are not NULL, they all are copied to the destination array; if only a single source channel of the first N is not NULL, this particular channel is copied into the destination array; otherwise an error is raised. The rest of the source channels (beyond the first N) must always be NULL. For IplImage -:ref:`Copy` -with COI set can be also used to insert a single channel into the image. - - -.. index:: Min - -.. _Min: - -Min ---- - - - - -.. function:: Min(src1,src2,dst)-> None - - Finds per-element minimum of two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - -The function calculates per-element minimum of two arrays: - - - -.. math:: - - \texttt{dst} (I)= \min ( \texttt{src1} (I), \texttt{src2} (I)) - - -All the arrays must have a single channel, the same data type and the same size (or ROI size). - - - -.. index:: MinMaxLoc - -.. _MinMaxLoc: - -MinMaxLoc ---------- - - - - -.. function:: MinMaxLoc(arr,mask=NULL)-> (minVal,maxVal,minLoc,maxLoc) - - Finds global minimum and maximum in array or subarray. - - - - - - - :param arr: The source array, single-channel or multi-channel with COI set - - :type arr: :class:`CvArr` - - - :param minVal: Pointer to returned minimum value - - :type minVal: float - - - :param maxVal: Pointer to returned maximum value - - :type maxVal: float - - - :param minLoc: Pointer to returned minimum location - - :type minLoc: :class:`CvPoint` - - - :param maxLoc: Pointer to returned maximum location - - :type maxLoc: :class:`CvPoint` - - - :param mask: The optional mask used to select a subarray - - :type mask: :class:`CvArr` - - - -The function finds minimum and maximum element values -and their positions. The extremums are searched across the whole array, -selected -``ROI`` -(in the case of -``IplImage`` -) or, if -``mask`` -is not -``NULL`` -, in the specified array region. If the array has -more than one channel, it must be -``IplImage`` -with -``COI`` -set. In the case of multi-dimensional arrays, -``minLoc->x`` -and -``maxLoc->x`` -will contain raw (linear) positions of the extremums. - - -.. index:: MinS - -.. _MinS: - -MinS ----- - - - - -.. function:: MinS(src,value,dst)-> None - - Finds per-element minimum of an array and a scalar. - - - - - - - :param src: The first source array - - :type src: :class:`CvArr` - - - :param value: The scalar value - - :type value: float - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - -The function calculates minimum of an array and a scalar: - - - -.. math:: - - \texttt{dst} (I)= \min ( \texttt{src} (I), \texttt{value} ) - - -All the arrays must have a single channel, the same data type and the same size (or ROI size). - - - -Mirror ------- - - -Synonym for -:ref:`Flip` -. - - -.. index:: MixChannels - -.. _MixChannels: - -MixChannels ------------ - - - - -.. function:: MixChannels(src, dst, fromTo) -> None - - Copies several channels from input arrays to certain channels of output arrays - - - - - - - :param src: Input arrays - - :type src: :class:`cvarr_count` - - - :param dst: Destination arrays - - :type dst: :class:`cvarr_count` - - - :param fromTo: The array of pairs of indices of the planes - copied. Each pair ``fromTo[k]=(i,j)`` - means that i-th plane from ``src`` is copied to the j-th plane in ``dst`` , where continuous - plane numbering is used both in the input array list and the output array list. - As a special case, when the ``fromTo[k][0]`` is negative, the corresponding output plane ``j`` - is filled with zero. - - :type fromTo: :class:`intpair` - - - -The function is a generalized form of -:ref:`cvSplit` -and -:ref:`Merge` -and some forms of -:ref:`CvtColor` -. It can be used to change the order of the -planes, add/remove alpha channel, extract or insert a single plane or -multiple planes etc. - -As an example, this code splits a 4-channel RGBA image into a 3-channel -BGR (i.e. with R and B swapped) and separate alpha channel image: - - - - -:: - - - - rgba = cv.CreateMat(100, 100, cv.CV_8UC4) - bgr = cv.CreateMat(100, 100, cv.CV_8UC3) - alpha = cv.CreateMat(100, 100, cv.CV_8UC1) - cv.Set(rgba, (1,2,3,4)) - cv.MixChannels([rgba], [bgr, alpha], [ - (0, 2), # rgba[0] -> bgr[2] - (1, 1), # rgba[1] -> bgr[1] - (2, 0), # rgba[2] -> bgr[0] - (3, 3) # rgba[3] -> alpha[0] - ]) - - -.. - - -MulAddS -------- - - -Synonym for -:ref:`ScaleAdd` -. - - -.. index:: Mul - -.. _Mul: - -Mul ---- - - - - -.. function:: Mul(src1,src2,dst,scale)-> None - - Calculates the per-element product of two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param scale: Optional scale factor - - :type scale: float - - - -The function calculates the per-element product of two arrays: - - - -.. math:: - - \texttt{dst} (I)= \texttt{scale} \cdot \texttt{src1} (I) \cdot \texttt{src2} (I) - - -All the arrays must have the same type and the same size (or ROI size). -For types that have limited range this operation is saturating. - - -.. index:: MulSpectrums - -.. _MulSpectrums: - -MulSpectrums ------------- - - - - -.. function:: MulSpectrums(src1,src2,dst,flags)-> None - - Performs per-element multiplication of two Fourier spectrums. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array of the same type and the same size as the source arrays - - :type dst: :class:`CvArr` - - - :param flags: A combination of the following values; - - * **CV_DXT_ROWS** treats each row of the arrays as a separate spectrum (see :ref:`DFT` parameters description). - - * **CV_DXT_MUL_CONJ** conjugate the second source array before the multiplication. - - - - :type flags: int - - - -The function performs 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 -:ref:`DFT` -, may be used to calculate convolution of two arrays rapidly. - - - -.. index:: MulTransposed - -.. _MulTransposed: - -MulTransposed -------------- - - - - -.. function:: MulTransposed(src,dst,order,delta=NULL,scale)-> None - - Calculates the product of an array and a transposed array. - - - - - - - :param src: The source matrix - - :type src: :class:`CvArr` - - - :param dst: The destination matrix. Must be ``CV_32F`` or ``CV_64F`` . - - :type dst: :class:`CvArr` - - - :param order: Order of multipliers - - :type order: int - - - :param delta: An optional array, subtracted from ``src`` before multiplication - - :type delta: :class:`CvArr` - - - :param scale: An optional scaling - - :type scale: float - - - -The function calculates the product of src and its transposition: - - - -.. math:: - - \texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} ) ( \texttt{src} - \texttt{delta} )^T - - -if -:math:`\texttt{order}=0` -, and - - - -.. math:: - - \texttt{dst} = \texttt{scale} ( \texttt{src} - \texttt{delta} )^T ( \texttt{src} - \texttt{delta} ) - - -otherwise. - - -.. index:: Norm - -.. _Norm: - -Norm ----- - - - - -.. function:: Norm(arr1,arr2,normType=CV_L2,mask=NULL)-> double - - Calculates absolute array norm, absolute difference norm, or relative difference norm. - - - - - - - :param arr1: The first source image - - :type arr1: :class:`CvArr` - - - :param arr2: The second source image. If it is NULL, the absolute norm of ``arr1`` is calculated, otherwise the absolute or relative norm of ``arr1`` - ``arr2`` is calculated. - - :type arr2: :class:`CvArr` - - - :param normType: Type of norm, see the discussion - - :type normType: int - - - :param mask: The optional operation mask - - :type mask: :class:`CvArr` - - - -The function calculates the absolute norm of -``arr1`` -if -``arr2`` -is NULL: - - -.. math:: - - norm = \forkthree{||\texttt{arr1}||_C = \max_I |\texttt{arr1}(I)|}{if $\texttt{normType} = \texttt{CV\_C}$}{||\texttt{arr1}||_{L1} = \sum_I |\texttt{arr1}(I)|}{if $\texttt{normType} = \texttt{CV\_L1}$}{||\texttt{arr1}||_{L2} = \sqrt{\sum_I \texttt{arr1}(I)^2}}{if $\texttt{normType} = \texttt{CV\_L2}$} - - -or the absolute difference norm if -``arr2`` -is not NULL: - - -.. math:: - - norm = \forkthree{||\texttt{arr1}-\texttt{arr2}||_C = \max_I |\texttt{arr1}(I) - \texttt{arr2}(I)|}{if $\texttt{normType} = \texttt{CV\_C}$}{||\texttt{arr1}-\texttt{arr2}||_{L1} = \sum_I |\texttt{arr1}(I) - \texttt{arr2}(I)|}{if $\texttt{normType} = \texttt{CV\_L1}$}{||\texttt{arr1}-\texttt{arr2}||_{L2} = \sqrt{\sum_I (\texttt{arr1}(I) - \texttt{arr2}(I))^2}}{if $\texttt{normType} = \texttt{CV\_L2}$} - - -or the relative difference norm if -``arr2`` -is not NULL and -``(normType & CV_RELATIVE) != 0`` -: - - - -.. math:: - - norm = \forkthree{\frac{||\texttt{arr1}-\texttt{arr2}||_C }{||\texttt{arr2}||_C }}{if $\texttt{normType} = \texttt{CV\_RELATIVE\_C}$}{\frac{||\texttt{arr1}-\texttt{arr2}||_{L1} }{||\texttt{arr2}||_{L1}}}{if $\texttt{normType} = \texttt{CV\_RELATIVE\_L1}$}{\frac{||\texttt{arr1}-\texttt{arr2}||_{L2} }{||\texttt{arr2}||_{L2}}}{if $\texttt{normType} = \texttt{CV\_RELATIVE\_L2}$} - - -The function returns the calculated norm. A multiple-channel array is treated as a single-channel, that is, the results for all channels are combined. - - -.. index:: Not - -.. _Not: - -Not ---- - - - - -.. function:: Not(src,dst)-> None - - Performs per-element bit-wise inversion of array elements. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - -The function Not inverses every bit of every array element: - - - - -:: - - - - dst(I)=~src(I) - - -.. - - -.. index:: Or - -.. _Or: - -Or --- - - - - -.. function:: Or(src1,src2,dst,mask=NULL)-> None - - Calculates per-element bit-wise disjunction of two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function calculates per-element bit-wise disjunction of two arrays: - - - - -:: - - - - dst(I)=src1(I)|src2(I) - - -.. - -In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - -.. index:: OrS - -.. _OrS: - -OrS ---- - - - - -.. function:: OrS(src,value,dst,mask=NULL)-> None - - Calculates a per-element bit-wise disjunction of an array and a scalar. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param value: Scalar to use in the operation - - :type value: :class:`CvScalar` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function OrS calculates per-element bit-wise disjunction of an array and a scalar: - - - - -:: - - - - dst(I)=src(I)|value if mask(I)!=0 - - -.. - -Prior to the actual operation, the scalar is converted to the same type as that of the array(s). In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - - -.. index:: PerspectiveTransform - -.. _PerspectiveTransform: - -PerspectiveTransform --------------------- - - - - -.. function:: PerspectiveTransform(src,dst,mat)-> None - - Performs perspective matrix transformation of a vector array. - - - - - - - :param src: The source three-channel floating-point array - - :type src: :class:`CvArr` - - - :param dst: The destination three-channel floating-point array - - :type dst: :class:`CvArr` - - - :param mat: :math:`3\times 3` or :math:`4 \times 4` transformation matrix - - :type mat: :class:`CvMat` - - - -The function transforms every element of -``src`` -(by treating it as 2D or 3D vector) in the following way: - - - -.. math:: - - (x, y, z) \rightarrow (x'/w, y'/w, z'/w) - - -where - - - -.. math:: - - (x', y', z', w') = \texttt{mat} \cdot \begin{bmatrix} x & y & z & 1 \end{bmatrix} - - -and - - -.. math:: - - w = \fork{w'}{if $w' \ne 0$}{\infty}{otherwise} - - - -.. index:: PolarToCart - -.. _PolarToCart: - -PolarToCart ------------ - - - - -.. function:: PolarToCart(magnitude,angle,x,y,angleInDegrees=0)-> None - - Calculates Cartesian coordinates of 2d vectors represented in polar form. - - - - - - - :param magnitude: The array of magnitudes. If it is NULL, the magnitudes are assumed to be all 1's. - - :type magnitude: :class:`CvArr` - - - :param angle: The array of angles, whether in radians or degrees - - :type angle: :class:`CvArr` - - - :param x: The destination array of x-coordinates, may be set to NULL if it is not needed - - :type x: :class:`CvArr` - - - :param y: The destination array of y-coordinates, mau be set to NULL if it is not needed - - :type y: :class:`CvArr` - - - :param angleInDegrees: The flag indicating whether the angles are measured in radians, which is default mode, or in degrees - - :type angleInDegrees: int - - - -The function calculates either the x-coodinate, y-coordinate or both of every vector -``magnitude(I)*exp(angle(I)*j), j=sqrt(-1)`` -: - - - - -:: - - - - x(I)=magnitude(I)*cos(angle(I)), - y(I)=magnitude(I)*sin(angle(I)) - - -.. - - -.. index:: Pow - -.. _Pow: - -Pow ---- - - - - -.. function:: Pow(src,dst,power)-> None - - Raises every array element to a power. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param dst: The destination array, should be the same type as the source - - :type dst: :class:`CvArr` - - - :param power: The exponent of power - - :type power: float - - - -The function raises every element of the input array to -``p`` -: - - - -.. math:: - - \texttt{dst} [I] = \fork{\texttt{src}(I)^p}{if \texttt{p} is integer}{|\texttt{src}(I)^p|}{otherwise} - - -That is, 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, as the following example, computing the cube root of array elements, shows: - - - - -.. doctest:: - - - - >>> import cv - >>> src = cv.CreateMat(1, 10, cv.CV_32FC1) - >>> mask = cv.CreateMat(src.rows, src.cols, cv.CV_8UC1) - >>> dst = cv.CreateMat(src.rows, src.cols, cv.CV_32FC1) - >>> cv.CmpS(src, 0, mask, cv.CV_CMP_LT) # find negative elements - >>> cv.Pow(src, dst, 1. / 3) - >>> cv.SubRS(dst, cv.ScalarAll(0), dst, mask) # negate the results of negative inputs - - -.. - -For some values of -``power`` -, such as integer values, 0.5, and -0.5, specialized faster algorithms are used. - - -.. index:: RNG - -.. _RNG: - -RNG ---- - - - - -.. function:: RNG(seed=-1LL)-> CvRNG - - Initializes a random number generator state. - - - - - - - :param seed: 64-bit value used to initiate a random sequence - - :type seed: :class:`int64` - - - -The function initializes a random number generator -and returns the state. The pointer to the state can be then passed to the -:ref:`RandInt` -, -:ref:`RandReal` -and -:ref:`RandArr` -functions. In the -current implementation a multiply-with-carry generator is used. - - -.. index:: RandArr - -.. _RandArr: - -RandArr -------- - - - - -.. function:: RandArr(rng,arr,distType,param1,param2)-> None - - Fills an array with random numbers and updates the RNG state. - - - - - - - :param rng: RNG state initialized by :ref:`RNG` - - :type rng: :class:`CvRNG` - - - :param arr: The destination array - - :type arr: :class:`CvArr` - - - :param distType: Distribution type - - * **CV_RAND_UNI** uniform distribution - - * **CV_RAND_NORMAL** normal or Gaussian distribution - - - - :type distType: int - - - :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. - - :type param1: :class:`CvScalar` - - - :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. - - :type param2: :class:`CvScalar` - - - -The function fills the destination array with uniformly -or normally distributed random numbers. - - -.. index:: RandInt - -.. _RandInt: - -RandInt -------- - - - - -.. function:: RandInt(rng)-> unsigned - - Returns a 32-bit unsigned integer and updates RNG. - - - - - - - :param rng: RNG state initialized by ``RandInit`` and, optionally, customized by ``RandSetRange`` (though, the latter function does not affect the discussed function outcome) - - :type rng: :class:`CvRNG` - - - -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, but it always generates a 32-bit number -whereas rand() returns a number in between 0 and -``RAND_MAX`` -which is -:math:`2^{16}` -or -:math:`2^{32}` -, depending on the platform. - -The function is useful for generating scalar random numbers, such as -points, patch sizes, table indices, etc., where integer numbers of a certain -range can be generated using a modulo operation and floating-point numbers -can be generated by scaling from 0 to 1 or any other specific range. - - -.. index:: RandReal - -.. _RandReal: - -RandReal --------- - - - - -.. function:: RandReal(rng)-> double - - Returns a floating-point random number and updates RNG. - - - - - - - :param rng: RNG state initialized by :ref:`RNG` - - :type rng: :class:`CvRNG` - - - -The function returns a uniformly-distributed random floating-point number between 0 and 1 (1 is not included). - - -.. index:: Reduce - -.. _Reduce: - -Reduce ------- - - - - -.. function:: Reduce(src,dst,dim=-1,op=CV_REDUCE_SUM)-> None - - Reduces a matrix to a vector. - - - - - - - :param src: The input matrix. - - :type src: :class:`CvArr` - - - :param dst: The output single-row/single-column vector that accumulates somehow all the matrix rows/columns. - - :type dst: :class:`CvArr` - - - :param dim: The 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 and -1 means that the dimension is chosen automatically by analysing the dst size. - - :type dim: int - - - :param op: The reduction operation. It can take of the following values: - - * **CV_REDUCE_SUM** The output is the sum of all of the matrix's rows/columns. - - * **CV_REDUCE_AVG** The output is the mean vector of all of the matrix's rows/columns. - - * **CV_REDUCE_MAX** The output is the maximum (column/row-wise) of all of the matrix's rows/columns. - - * **CV_REDUCE_MIN** The output is the minimum (column/row-wise) of all of the matrix's rows/columns. - - - - :type op: int - - - -The function reduces 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 an raster image. In the case of -``CV_REDUCE_SUM`` -and -``CV_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. - - -.. index:: Repeat - -.. _Repeat: - -Repeat ------- - - - - -.. function:: Repeat(src,dst)-> None - - Fill the destination array with repeated copies of the source array. - - - - - - - :param src: Source array, image or matrix - - :type src: :class:`CvArr` - - - :param dst: Destination array, image or matrix - - :type dst: :class:`CvArr` - - - -The function fills the destination array with repeated copies of the source array: - - - - -:: - - - - dst(i,j)=src(i mod rows(src), j mod cols(src)) - - -.. - -So the destination array may be as larger as well as smaller than the source array. - - -.. index:: ResetImageROI - -.. _ResetImageROI: - -ResetImageROI -------------- - - - - -.. function:: ResetImageROI(image)-> None - - Resets the image ROI to include the entire image and releases the ROI structure. - - - - - - - :param image: A pointer to the image header - - :type image: :class:`IplImage` - - - -This produces a similar result to the following - - - -:: - - - - cv.SetImageROI(image, (0, 0, image.width, image.height)) - cv.SetImageCOI(image, 0) - - -.. - - -.. index:: Reshape - -.. _Reshape: - -Reshape -------- - - - - -.. function:: Reshape(arr, newCn, newRows=0) -> cvmat - - Changes shape of matrix/image without copying data. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param newCn: New number of channels. 'newCn = 0' means that the number of channels remains unchanged. - - :type newCn: int - - - :param newRows: New number of rows. 'newRows = 0' means that the number of rows remains unchanged unless it needs to be changed according to ``newCn`` value. - - :type newRows: int - - - -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. - - -.. index:: ReshapeMatND - -.. _ReshapeMatND: - -ReshapeMatND ------------- - - - - -.. function:: ReshapeMatND(arr, newCn, newDims) -> cvmat - - Changes the shape of a multi-dimensional array without copying the data. - - - - - - - :param arr: Input array - - :type arr: :class:`CvMat` - - - :param newCn: New number of channels. :math:`\texttt{newCn} = 0` means that the number of channels remains unchanged. - - :type newCn: int - - - :param newDims: List of new dimensions. - - :type newDims: sequence of int - - - -Returns a new -:ref:`CvMatND` -that shares the same data as -``arr`` -but has different dimensions or number of channels. The only requirement -is that the total length of the data is unchanged. - - - - -.. doctest:: - - - - >>> import cv - >>> mat = cv.CreateMatND([24], cv.CV_32FC1) - >>> print cv.GetDims(cv.ReshapeMatND(mat, 0, [8, 3])) - (8, 3) - >>> m2 = cv.ReshapeMatND(mat, 4, [3, 2]) - >>> print cv.GetDims(m2) - (3, 2) - >>> print m2.channels - 4 - - -.. - - -.. index:: Round - -.. _Round: - -Round ------ - - - - -.. function:: Round(value) -> int - - Converts a floating-point number to the nearest integer value. - - - - - - - :param value: The input floating-point value - - :type value: float - - - -On some architectures this function is much faster than the standard cast -operations. If the absolute value of the argument is greater than -:math:`2^{31}` -, the result is not determined. Special values ( -:math:`\pm \infty` -, NaN) -are not handled. - - -.. index:: Floor - -.. _Floor: - -Floor ------ - - - - -.. function:: Floor(value) -> int - - Converts a floating-point number to the nearest integer value that is not larger than the argument. - - - - - - - :param value: The input floating-point value - - :type value: float - - - -On some architectures this function is much faster than the standard cast -operations. If the absolute value of the argument is greater than -:math:`2^{31}` -, the result is not determined. Special values ( -:math:`\pm \infty` -, NaN) -are not handled. - - -.. index:: Ceil - -.. _Ceil: - -Ceil ----- - - - - -.. function:: Ceil(value) -> int - - Converts a floating-point number to the nearest integer value that is not smaller than the argument. - - - - - - - :param value: The input floating-point value - - :type value: float - - - -On some architectures this function is much faster than the standard cast -operations. If the absolute value of the argument is greater than -:math:`2^{31}` -, the result is not determined. Special values ( -:math:`\pm \infty` -, NaN) -are not handled. - - -.. index:: ScaleAdd - -.. _ScaleAdd: - -ScaleAdd --------- - - - - -.. function:: ScaleAdd(src1,scale,src2,dst)-> None - - Calculates the sum of a scaled array and another array. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param scale: Scale factor for the first array - - :type scale: :class:`CvScalar` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - -The function calculates the sum of a scaled array and another array: - - - -.. math:: - - \texttt{dst} (I)= \texttt{scale} \, \texttt{src1} (I) + \texttt{src2} (I) - - -All array parameters should have the same type and the same size. - - -.. index:: Set - -.. _Set: - -Set ---- - - - - -.. function:: Set(arr,value,mask=NULL)-> None - - Sets every element of an array to a given value. - - - - - - - :param arr: The destination array - - :type arr: :class:`CvArr` - - - :param value: Fill value - - :type value: :class:`CvScalar` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function copies the scalar -``value`` -to every selected element of the destination array: - - - -.. math:: - - \texttt{arr} (I)= \texttt{value} \quad \text{if} \quad \texttt{mask} (I) \ne 0 - - -If array -``arr`` -is of -``IplImage`` -type, then is ROI used, but COI must not be set. - - -.. index:: Set1D - -.. _Set1D: - -Set1D ------ - - - - -.. function:: Set1D(arr, idx, value) -> None - - Set a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx: Zero-based element index - - :type idx: int - - - :param value: The value to assign to the element - - :type value: :class:`CvScalar` - - - -Sets a specific array element. Array must have dimension 1. - - -.. index:: Set2D - -.. _Set2D: - -Set2D ------ - - - - -.. function:: Set2D(arr, idx0, idx1, value) -> None - - Set a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx0: Zero-based element row index - - :type idx0: int - - - :param idx1: Zero-based element column index - - :type idx1: int - - - :param value: The value to assign to the element - - :type value: :class:`CvScalar` - - - -Sets a specific array element. Array must have dimension 2. - - -.. index:: Set3D - -.. _Set3D: - -Set3D ------ - - - - -.. function:: Set3D(arr, idx0, idx1, idx2, value) -> None - - Set a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx0: Zero-based element index - - :type idx0: int - - - :param idx1: Zero-based element index - - :type idx1: int - - - :param idx2: Zero-based element index - - :type idx2: int - - - :param value: The value to assign to the element - - :type value: :class:`CvScalar` - - - -Sets a specific array element. Array must have dimension 3. - - -.. index:: SetND - -.. _SetND: - -SetND ------ - - - - -.. function:: SetND(arr, indices, value) -> None - - Set a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param indices: List of zero-based element indices - - :type indices: sequence of int - - - :param value: The value to assign to the element - - :type value: :class:`CvScalar` - - - -Sets a specific array element. The length of array indices must be the same as the dimension of the array. - -.. index:: SetData - -.. _SetData: - -SetData -------- - - - - -.. function:: SetData(arr, data, step)-> None - - Assigns user data to the array header. - - - - - - - :param arr: Array header - - :type arr: :class:`CvArr` - - - :param data: User data - - :type data: object - - - :param step: Full row length in bytes - - :type step: int - - - -The function assigns user data to the array header. Header should be initialized before using -``cvCreate*Header`` -, -``cvInit*Header`` -or -:ref:`Mat` -(in the case of matrix) function. - - -.. index:: SetIdentity - -.. _SetIdentity: - -SetIdentity ------------ - - - - -.. function:: SetIdentity(mat,value=1)-> None - - Initializes a scaled identity matrix. - - - - - - - :param mat: The matrix to initialize (not necesserily square) - - :type mat: :class:`CvArr` - - - :param value: The value to assign to the diagonal elements - - :type value: :class:`CvScalar` - - - -The function initializes a scaled identity matrix: - - - -.. math:: - - \texttt{arr} (i,j)= \fork{\texttt{value}}{ if $i=j$}{0}{otherwise} - - - -.. index:: SetImageCOI - -.. _SetImageCOI: - -SetImageCOI ------------ - - - - -.. function:: SetImageCOI(image, coi)-> None - - Sets the channel of interest in an IplImage. - - - - - - - :param image: A pointer to the image header - - :type image: :class:`IplImage` - - - :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. - - :type coi: int - - - -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 -:ref:`Copy` -or -:ref:`Split` -) the channel to a separate -image/matrix, process it and then copy the result back (via -:ref:`Copy` -or -:ref:`Merge` -) if needed. - - -.. index:: SetImageROI - -.. _SetImageROI: - -SetImageROI ------------ - - - - -.. function:: SetImageROI(image, rect)-> None - - Sets an image Region Of Interest (ROI) for a given rectangle. - - - - - - - :param image: A pointer to the image header - - :type image: :class:`IplImage` - - - :param rect: The ROI rectangle - - :type rect: :class:`CvRect` - - - -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. - - -.. index:: SetReal1D - -.. _SetReal1D: - -SetReal1D ---------- - - - - -.. function:: SetReal1D(arr, idx, value) -> None - - Set a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx: Zero-based element index - - :type idx: int - - - :param value: The value to assign to the element - - :type value: float - - - -Sets a specific array element. Array must have dimension 1. - - -.. index:: SetReal2D - -.. _SetReal2D: - -SetReal2D ---------- - - - - -.. function:: SetReal2D(arr, idx0, idx1, value) -> None - - Set a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx0: Zero-based element row index - - :type idx0: int - - - :param idx1: Zero-based element column index - - :type idx1: int - - - :param value: The value to assign to the element - - :type value: float - - - -Sets a specific array element. Array must have dimension 2. - - -.. index:: SetReal3D - -.. _SetReal3D: - -SetReal3D ---------- - - - - -.. function:: SetReal3D(arr, idx0, idx1, idx2, value) -> None - - Set a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param idx0: Zero-based element index - - :type idx0: int - - - :param idx1: Zero-based element index - - :type idx1: int - - - :param idx2: Zero-based element index - - :type idx2: int - - - :param value: The value to assign to the element - - :type value: float - - - -Sets a specific array element. Array must have dimension 3. - - -.. index:: SetRealND - -.. _SetRealND: - -SetRealND ---------- - - - - -.. function:: SetRealND(arr, indices, value) -> None - - Set a specific array element. - - - - - - - :param arr: Input array - - :type arr: :class:`CvArr` - - - :param indices: List of zero-based element indices - - :type indices: sequence of int - - - :param value: The value to assign to the element - - :type value: float - - - -Sets a specific array element. The length of array indices must be the same as the dimension of the array. - -.. index:: SetZero - -.. _SetZero: - -SetZero -------- - - - - -.. function:: SetZero(arr)-> None - - Clears the array. - - - - - - - :param arr: Array to be cleared - - :type arr: :class:`CvArr` - - - -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. - - -.. index:: Solve - -.. _Solve: - -Solve ------ - - - - -.. function:: Solve(A,B,X,method=CV_LU)-> None - - Solves a linear system or least-squares problem. - - - - - - - :param A: The source matrix - - :type A: :class:`CvArr` - - - :param B: The right-hand part of the linear system - - :type B: :class:`CvArr` - - - :param X: The output solution - - :type X: :class:`CvArr` - - - :param method: The solution (matrix inversion) method - - - * **CV_LU** Gaussian elimination with optimal pivot element chosen - - - * **CV_SVD** Singular value decomposition (SVD) method - - - * **CV_SVD_SYM** SVD method for a symmetric positively-defined matrix. - - - - :type method: int - - - -The function solves a linear system or least-squares problem (the latter is possible with SVD methods): - - - -.. math:: - - \texttt{dst} = argmin_X|| \texttt{src1} \, \texttt{X} - \texttt{src2} || - - -If -``CV_LU`` -method is used, the function returns 1 if -``src1`` -is non-singular and 0 otherwise; in the latter case -``dst`` -is not valid. - - -.. index:: SolveCubic - -.. _SolveCubic: - -SolveCubic ----------- - - - - -.. function:: SolveCubic(coeffs,roots)-> None - - Finds the real roots of a cubic equation. - - - - - - - :param coeffs: The equation coefficients, an array of 3 or 4 elements - - :type coeffs: :class:`CvMat` - - - :param roots: The output array of real roots which should have 3 elements - - :type roots: :class:`CvMat` - - - -The function finds the real roots of a cubic equation: - -If coeffs is a 4-element vector: - - - -.. math:: - - \texttt{coeffs} [0] x^3 + \texttt{coeffs} [1] x^2 + \texttt{coeffs} [2] x + \texttt{coeffs} [3] = 0 - - -or if coeffs is 3-element vector: - - - -.. math:: - - x^3 + \texttt{coeffs} [0] x^2 + \texttt{coeffs} [1] x + \texttt{coeffs} [2] = 0 - - -The function returns the number of real roots found. The roots are -stored to -``root`` -array, which is padded with zeros if there is -only one root. - - -.. index:: Split - -.. _Split: - -Split ------ - - - - -.. function:: Split(src,dst0,dst1,dst2,dst3)-> None - - Divides multi-channel array into several single-channel arrays or extracts a single channel from the array. - - - - - - - :param src: Source array - - :type src: :class:`CvArr` - - - :param dst0: Destination channel 0 - - :type dst0: :class:`CvArr` - - - :param dst1: Destination channel 1 - - :type dst1: :class:`CvArr` - - - :param dst2: Destination channel 2 - - :type dst2: :class:`CvArr` - - - :param dst3: Destination channel 3 - - :type dst3: :class:`CvArr` - - - -The function divides a multi-channel array into separate -single-channel arrays. Two modes are available for the operation. If the -source array has N channels then if the first N destination channels -are not NULL, they all are extracted from the source array; -if only a single destination channel of the first N is not NULL, this -particular channel is extracted; otherwise an error is raised. The rest -of the destination channels (beyond the first N) must always be NULL. For -IplImage -:ref:`Copy` -with COI set can be also used to extract a single -channel from the image. - - - -.. index:: Sqrt - -.. _Sqrt: - -Sqrt ----- - - - - -.. function:: Sqrt(value)-> float - - Calculates the square root. - - - - - - - :param value: The input floating-point value - - :type value: float - - - -The function calculates the square root of the argument. If the argument is negative, the result is not determined. - - -.. index:: Sub - -.. _Sub: - -Sub ---- - - - - -.. function:: Sub(src1,src2,dst,mask=NULL)-> None - - Computes the per-element difference between two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function subtracts one array from another one: - - - - -:: - - - - dst(I)=src1(I)-src2(I) if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). -For types that have limited range this operation is saturating. - - -.. index:: SubRS - -.. _SubRS: - -SubRS ------ - - - - -.. function:: SubRS(src,value,dst,mask=NULL)-> None - - Computes the difference between a scalar and an array. - - - - - - - :param src: The first source array - - :type src: :class:`CvArr` - - - :param value: Scalar to subtract from - - :type value: :class:`CvScalar` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function subtracts every element of source array from a scalar: - - - - -:: - - - - dst(I)=value-src(I) if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). -For types that have limited range this operation is saturating. - - -.. index:: SubS - -.. _SubS: - -SubS ----- - - - - -.. function:: SubS(src,value,dst,mask=NULL)-> None - - Computes the difference between an array and a scalar. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param value: Subtracted scalar - - :type value: :class:`CvScalar` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function subtracts a scalar from every element of the source array: - - - - -:: - - - - dst(I)=src(I)-value if mask(I)!=0 - - -.. - -All the arrays must have the same type, except the mask, and the same size (or ROI size). -For types that have limited range this operation is saturating. - - - -.. index:: Sum - -.. _Sum: - -Sum ---- - - - - -.. function:: Sum(arr)-> CvScalar - - Adds up array elements. - - - - - - - :param arr: The array - - :type arr: :class:`CvArr` - - - -The function calculates the sum -``S`` -of array elements, independently for each channel: - - - -.. math:: - - \sum _I \texttt{arr} (I)_c - - -If the array is -``IplImage`` -and COI is set, the function processes the selected channel only and stores the sum to the first scalar component. - - - -.. index:: SVBkSb - -.. _SVBkSb: - -SVBkSb ------- - - - - -.. function:: SVBkSb(W,U,V,B,X,flags)-> None - - Performs singular value back substitution. - - - - - - - :param W: Matrix or vector of singular values - - :type W: :class:`CvArr` - - - :param U: Left orthogonal matrix (tranposed, perhaps) - - :type U: :class:`CvArr` - - - :param V: Right orthogonal matrix (tranposed, perhaps) - - :type V: :class:`CvArr` - - - :param B: The matrix to multiply the pseudo-inverse of the original matrix ``A`` by. This is an optional parameter. If it is omitted then it is assumed to be an identity matrix of an appropriate size (so that ``X`` will be the reconstructed pseudo-inverse of ``A`` ). - - :type B: :class:`CvArr` - - - :param X: The destination matrix: result of back substitution - - :type X: :class:`CvArr` - - - :param flags: Operation flags, should match exactly to the ``flags`` passed to :ref:`SVD` - - :type flags: int - - - -The function calculates back substitution for decomposed matrix -``A`` -(see -:ref:`SVD` -description) and matrix -``B`` -: - - - -.. math:: - - \texttt{X} = \texttt{V} \texttt{W} ^{-1} \texttt{U} ^T \texttt{B} - - -where - - - -.. math:: - - W^{-1}_{(i,i)}= \fork{1/W_{(i,i)}}{if $W_{(i,i)} > \epsilon \sum_i{W_{(i,i)}}$ }{0}{otherwise} - - -and -:math:`\epsilon` -is a small number that depends on the matrix data type. - -This function together with -:ref:`SVD` -is used inside -:ref:`Invert` -and -:ref:`Solve` -, and the possible reason to use these (svd and bksb) -"low-level" function, is to avoid allocation of temporary matrices inside -the high-level counterparts (inv and solve). - - -.. index:: SVD - -.. _SVD: - -SVD ---- - - - - -.. function:: SVD(A,W, U = None, V = None, flags=0)-> None - - Performs singular value decomposition of a real floating-point matrix. - - - - - - - :param A: Source :math:`\texttt{M} \times \texttt{N}` matrix - - :type A: :class:`CvArr` - - - :param W: Resulting singular value diagonal matrix ( :math:`\texttt{M} \times \texttt{N}` or :math:`\min(\texttt{M}, \texttt{N}) \times \min(\texttt{M}, \texttt{N})` ) or :math:`\min(\texttt{M},\texttt{N}) \times 1` vector of the singular values - - :type W: :class:`CvArr` - - - :param U: Optional left orthogonal matrix, :math:`\texttt{M} \times \min(\texttt{M}, \texttt{N})` (when ``CV_SVD_U_T`` is not set), or :math:`\min(\texttt{M},\texttt{N}) \times \texttt{M}` (when ``CV_SVD_U_T`` is set), or :math:`\texttt{M} \times \texttt{M}` (regardless of ``CV_SVD_U_T`` flag). - - :type U: :class:`CvArr` - - - :param V: Optional right orthogonal matrix, :math:`\texttt{N} \times \min(\texttt{M}, \texttt{N})` (when ``CV_SVD_V_T`` is not set), or :math:`\min(\texttt{M},\texttt{N}) \times \texttt{N}` (when ``CV_SVD_V_T`` is set), or :math:`\texttt{N} \times \texttt{N}` (regardless of ``CV_SVD_V_T`` flag). - - :type V: :class:`CvArr` - - - :param flags: Operation flags; can be 0 or a combination of the following values: - - - * **CV_SVD_MODIFY_A** enables modification of matrix ``A`` during the operation. It speeds up the processing. - - - * **CV_SVD_U_T** means that the transposed matrix ``U`` is returned. Specifying the flag speeds up the processing. - - - * **CV_SVD_V_T** means that the transposed matrix ``V`` is returned. Specifying the flag speeds up the processing. - - - - :type flags: int - - - -The function decomposes matrix -``A`` -into the product of a diagonal matrix and two - -orthogonal matrices: - - - -.. math:: - - A=U \, W \, V^T - - -where -:math:`W` -is a diagonal matrix of singular values that can be coded as a -1D vector of singular values and -:math:`U` -and -:math:`V` -. All the singular values -are non-negative and sorted (together with -:math:`U` -and -:math:`V` -columns) -in descending order. - -An SVD algorithm is numerically robust and its typical applications include: - - - - - -* - accurate eigenvalue problem solution when matrix - ``A`` - is a square, symmetric, and positively defined matrix, for example, when - it is a covariance matrix. - :math:`W` - in this case will be a vector/matrix - of the eigenvalues, and - :math:`U = V` - will be a matrix of the eigenvectors. - - - -* - accurate solution of a poor-conditioned linear system. - - - -* - least-squares solution of an overdetermined linear system. This and the preceeding is done by using the - :ref:`Solve` - function with the - ``CV_SVD`` - method. - - - -* - accurate calculation of different matrix characteristics such as the matrix rank (the number of non-zero singular values), condition number (ratio of the largest singular value to the smallest one), and determinant (absolute value of the determinant is equal to the product of singular values). - - - -.. index:: Trace - -.. _Trace: - -Trace ------ - - - - -.. function:: Trace(mat)-> CvScalar - - Returns the trace of a matrix. - - - - - - - :param mat: The source matrix - - :type mat: :class:`CvArr` - - - -The function returns the sum of the diagonal elements of the matrix -``src1`` -. - - - -.. math:: - - tr( \texttt{mat} ) = \sum _i \texttt{mat} (i,i) - - - -.. index:: Transform - -.. _Transform: - -Transform ---------- - - - - -.. function:: Transform(src,dst,transmat,shiftvec=NULL)-> None - - Performs matrix transformation of every array element. - - - - - - - :param src: The first source array - - :type src: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param transmat: Transformation matrix - - :type transmat: :class:`CvMat` - - - :param shiftvec: Optional shift vector - - :type shiftvec: :class:`CvMat` - - - -The function performs matrix transformation of every element of array -``src`` -and stores the results in -``dst`` -: - - - -.. math:: - - dst(I) = transmat \cdot src(I) + shiftvec - - -That is, every element of an -``N`` --channel array -``src`` -is -considered as an -``N`` --element vector which is transformed using -a -:math:`\texttt{M} \times \texttt{N}` -matrix -``transmat`` -and shift -vector -``shiftvec`` -into an element of -``M`` --channel array -``dst`` -. There is an option to embedd -``shiftvec`` -into -``transmat`` -. In this case -``transmat`` -should be a -:math:`\texttt{M} -\times (N+1)` -matrix and the rightmost column is treated as the shift -vector. - -Both source and destination arrays should have the same depth and the -same size or selected ROI size. -``transmat`` -and -``shiftvec`` -should be real floating-point matrices. - -The function may be used for geometrical transformation of n dimensional -point set, arbitrary linear color space transformation, shuffling the -channels and so forth. - - -.. index:: Transpose - -.. _Transpose: - -Transpose ---------- - - - - -.. function:: Transpose(src,dst)-> None - - Transposes a matrix. - - - - - - - :param src: The source matrix - - :type src: :class:`CvArr` - - - :param dst: The destination matrix - - :type dst: :class:`CvArr` - - - -The function transposes matrix -``src1`` -: - - - -.. math:: - - \texttt{dst} (i,j) = \texttt{src} (j,i) - - -Note that no complex conjugation is done in the case of a complex -matrix. Conjugation should be done separately: look at the sample code -in -:ref:`XorS` -for an example. - - -.. index:: Xor - -.. _Xor: - -Xor ---- - - - - -.. function:: Xor(src1,src2,dst,mask=NULL)-> None - - Performs per-element bit-wise "exclusive or" operation on two arrays. - - - - - - - :param src1: The first source array - - :type src1: :class:`CvArr` - - - :param src2: The second source array - - :type src2: :class:`CvArr` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function calculates per-element bit-wise logical conjunction of two arrays: - - - - -:: - - - - dst(I)=src1(I)^src2(I) if mask(I)!=0 - - -.. - -In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size. - - -.. index:: XorS - -.. _XorS: - -XorS ----- - - - - -.. function:: XorS(src,value,dst,mask=NULL)-> None - - Performs per-element bit-wise "exclusive or" operation on an array and a scalar. - - - - - - - :param src: The source array - - :type src: :class:`CvArr` - - - :param value: Scalar to use in the operation - - :type value: :class:`CvScalar` - - - :param dst: The destination array - - :type dst: :class:`CvArr` - - - :param mask: Operation mask, 8-bit single channel array; specifies elements of the destination array to be changed - - :type mask: :class:`CvArr` - - - -The function XorS calculates per-element bit-wise conjunction of an array and a scalar: - - - - -:: - - - - dst(I)=src(I)^value if mask(I)!=0 - - -.. - -Prior to the actual operation, the scalar is converted to the same type as that of the array(s). In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size - - -.. index:: mGet - -.. _mGet: - -mGet ----- - - - - -.. function:: mGet(mat,row,col)-> double - - Returns the particular element of single-channel floating-point matrix. - - - - - - - :param mat: Input matrix - - :type mat: :class:`CvMat` - - - :param row: The zero-based index of row - - :type row: int - - - :param col: The zero-based index of column - - :type col: int - - - -The function is a fast replacement for -:ref:`GetReal2D` -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. - - -.. index:: mSet - -.. _mSet: - -mSet ----- - - - - -.. function:: mSet(mat,row,col,value)-> None - - Returns a specific element of a single-channel floating-point matrix. - - - - - - - :param mat: The matrix - - :type mat: :class:`CvMat` - - - :param row: The zero-based index of row - - :type row: int - - - :param col: The zero-based index of column - - :type col: int - - - :param value: The new value of the matrix element - - :type value: float - - - -The function is a fast replacement for -:ref:`SetReal2D` -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. - diff --git a/doc/opencv1/py/core_utility_and_system_functions_and_macros.rst b/doc/opencv1/py/core_utility_and_system_functions_and_macros.rst deleted file mode 100644 index 2b310c2699..0000000000 --- a/doc/opencv1/py/core_utility_and_system_functions_and_macros.rst +++ /dev/null @@ -1,99 +0,0 @@ -Utility and System Functions and Macros -======================================= - -.. highlight:: python - - - -Error Handling --------------- - - -Errors in argument type cause a -``TypeError`` -exception. -OpenCV errors cause an -``cv.error`` -exception. - -For example a function argument that is the wrong type produces a -``TypeError`` -: - - - - -.. doctest:: - - - - >>> import cv - >>> cv.LoadImage(4) - Traceback (most recent call last): - File "", line 1, in - TypeError: argument 1 must be string, not int - - -.. - -A function with the - - - - -.. doctest:: - - - - >>> cv.CreateMat(-1, -1, cv.CV_8UC1) - Traceback (most recent call last): - File "", line 1, in - error: Non-positive width or height - - -.. - - -.. index:: GetTickCount - -.. _GetTickCount: - -GetTickCount ------------- - - - - -.. function:: GetTickCount() -> long - - Returns the number of ticks. - - - -The function returns number of the ticks starting from some platform-dependent event (number of CPU ticks from the startup, number of milliseconds from 1970th year, etc.). The function is useful for accurate measurement of a function/user-code execution time. To convert the number of ticks to time units, use -:ref:`GetTickFrequency` -. - - -.. index:: GetTickFrequency - -.. _GetTickFrequency: - -GetTickFrequency ----------------- - - - - -.. function:: GetTickFrequency() -> long - - Returns the number of ticks per microsecond. - - - -The function returns the number of ticks per microsecond. Thus, the quotient of -:ref:`GetTickCount` -and -:ref:`GetTickFrequency` -will give the number of microseconds starting from the platform-dependent event. - diff --git a/doc/opencv1/py/core_xml_yaml_persistence.rst b/doc/opencv1/py/core_xml_yaml_persistence.rst deleted file mode 100644 index a981fb6e38..0000000000 --- a/doc/opencv1/py/core_xml_yaml_persistence.rst +++ /dev/null @@ -1,95 +0,0 @@ -XML/YAML Persistence -==================== - -.. highlight:: python - - - -.. index:: Load - -.. _Load: - -Load ----- - - - - -.. function:: Load(filename,storage=NULL,name=NULL)-> generic - - Loads an object from a file. - - - - - - - :param filename: File name - - :type filename: str - - - :param storage: Memory storage for dynamic structures, such as :ref:`CvSeq` or :ref:`CvGraph` . It is not used for matrices or images. - - :type storage: :class:`CvMemStorage` - - - :param name: Optional object name. If it is NULL, the first top-level object in the storage will be loaded. - - :type name: str - - - -The function loads an object from a file. It provides a -simple interface to -:ref:`Read` -. 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. - - -.. index:: Save - -.. _Save: - -Save ----- - - - - -.. function:: Save(filename,structPtr,name=NULL,comment=NULL)-> None - - Saves an object to a file. - - - - - - - :param filename: File name - - :type filename: str - - - :param structPtr: Object to save - - :type structPtr: :class:`generic` - - - :param name: Optional object name. If it is NULL, the name will be formed from ``filename`` . - - :type name: str - - - :param comment: Optional comment to put in the beginning of the file - - :type comment: str - - - -The function saves an object to a file. It provides a simple interface to -:ref:`Write` -. - diff --git a/doc/opencv1/py/features2d.rst b/doc/opencv1/py/features2d.rst deleted file mode 100644 index 4cd910920d..0000000000 --- a/doc/opencv1/py/features2d.rst +++ /dev/null @@ -1,10 +0,0 @@ -******************************************************* -features2d. Feature Detection and Descriptor Extraction -******************************************************* - - - -.. toctree:: - :maxdepth: 2 - - features2d_feature_detection_and_description diff --git a/doc/opencv1/py/features2d_feature_detection_and_description.rst b/doc/opencv1/py/features2d_feature_detection_and_description.rst deleted file mode 100644 index a5637e09af..0000000000 --- a/doc/opencv1/py/features2d_feature_detection_and_description.rst +++ /dev/null @@ -1,264 +0,0 @@ -Feature detection and description -================================= - -.. highlight:: python - - - - - - * **image** The image. Keypoints (corners) will be detected on this. - - - * **keypoints** Keypoints detected on the image. - - - * **threshold** Threshold on difference between intensity of center pixel and - pixels on circle around this pixel. See description of the algorithm. - - - * **nonmaxSupression** If it is true then non-maximum supression will be applied to detected corners (keypoints). - - - - -.. index:: CvSURFPoint - -.. _CvSURFPoint: - -CvSURFPoint ------------ - - - -.. class:: CvSURFPoint - - - -A SURF keypoint, represented as a tuple -``((x, y), laplacian, size, dir, hessian)`` -. - - - - - - .. attribute:: x - - - - x-coordinate of the feature within the image - - - - .. attribute:: y - - - - y-coordinate of the feature within the image - - - - .. attribute:: laplacian - - - - -1, 0 or +1. sign of the laplacian at the point. Can be used to speedup feature comparison since features with laplacians of different signs can not match - - - - .. attribute:: size - - - - size of the feature - - - - .. attribute:: dir - - - - orientation of the feature: 0..360 degrees - - - - .. attribute:: hessian - - - - value of the hessian (can be used to approximately estimate the feature strengths; see also params.hessianThreshold) - - - - -.. index:: ExtractSURF - -.. _ExtractSURF: - -ExtractSURF ------------ - - - - -.. function:: ExtractSURF(image,mask,storage,params)-> (keypoints,descriptors) - - Extracts Speeded Up Robust Features from an image. - - - - - - - :param image: The input 8-bit grayscale image - - :type image: :class:`CvArr` - - - :param mask: The optional input 8-bit mask. The features are only found in the areas that contain more than 50 % of non-zero mask pixels - - :type mask: :class:`CvArr` - - - :param keypoints: sequence of keypoints. - - :type keypoints: :class:`CvSeq` of :class:`CvSURFPoint` - - - :param descriptors: sequence of descriptors. Each SURF descriptor is a list of floats, of length 64 or 128. - - :type descriptors: :class:`CvSeq` of list of float - - - :param storage: Memory storage where keypoints and descriptors will be stored - - :type storage: :class:`CvMemStorage` - - - :param params: Various algorithm parameters in a tuple ``(extended, hessianThreshold, nOctaves, nOctaveLayers)`` : - - * **extended** 0 means basic descriptors (64 elements each), 1 means extended descriptors (128 elements each) - - * **hessianThreshold** only features with hessian larger than that are extracted. good default value is ~300-500 (can depend on the average local contrast and sharpness of the image). user can further filter out some features based on their hessian values and other characteristics. - - * **nOctaves** the number of octaves to be used for extraction. With each next octave the feature size is doubled (3 by default) - - * **nOctaveLayers** The number of layers within each octave (4 by default) - - - - :type params: :class:`CvSURFParams` - - - -The function cvExtractSURF finds robust features in the image, as -described in -Bay06 -. For each feature it returns its location, size, -orientation and optionally the descriptor, basic or extended. The function -can be used for object tracking and localization, image stitching etc. - -To extract strong SURF features from an image - - - - -.. doctest:: - - - - >>> import cv - >>> im = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE) - >>> (keypoints, descriptors) = cv.ExtractSURF(im, None, cv.CreateMemStorage(), (0, 30000, 3, 1)) - >>> print len(keypoints), len(descriptors) - 6 6 - >>> for ((x, y), laplacian, size, dir, hessian) in keypoints: - ... print "x=%d y=%d laplacian=%d size=%d dir=%f hessian=%f" % (x, y, laplacian, size, dir, hessian) - x=30 y=27 laplacian=-1 size=31 dir=69.778503 hessian=36979.789062 - x=296 y=197 laplacian=1 size=33 dir=111.081039 hessian=31514.349609 - x=296 y=266 laplacian=1 size=32 dir=107.092300 hessian=31477.908203 - x=254 y=284 laplacian=1 size=31 dir=279.137360 hessian=34169.800781 - x=498 y=525 laplacian=-1 size=33 dir=278.006592 hessian=31002.759766 - x=777 y=281 laplacian=1 size=70 dir=167.940964 hessian=35538.363281 - - -.. - - -.. index:: GetStarKeypoints - -.. _GetStarKeypoints: - -GetStarKeypoints ----------------- - - - - -.. function:: GetStarKeypoints(image,storage,params)-> keypoints - - Retrieves keypoints using the StarDetector algorithm. - - - - - - - :param image: The input 8-bit grayscale image - - :type image: :class:`CvArr` - - - :param storage: Memory storage where the keypoints will be stored - - :type storage: :class:`CvMemStorage` - - - :param params: Various algorithm parameters in a tuple ``(maxSize, responseThreshold, lineThresholdProjected, lineThresholdBinarized, suppressNonmaxSize)`` : - - * **maxSize** maximal size of the features detected. The following values of the parameter are supported: 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128 - - * **responseThreshold** threshold for the approximatd laplacian, used to eliminate weak features - - * **lineThresholdProjected** another threshold for laplacian to eliminate edges - - * **lineThresholdBinarized** another threshold for the feature scale to eliminate edges - - * **suppressNonmaxSize** linear size of a pixel neighborhood for non-maxima suppression - - - - :type params: :class:`CvStarDetectorParams` - - - -The function GetStarKeypoints extracts keypoints that are local -scale-space extremas. The scale-space is constructed by computing -approximate values of laplacians with different sigma's at each -pixel. Instead of using pyramids, a popular approach to save computing -time, all of the laplacians are computed at each pixel of the original -high-resolution image. But each approximate laplacian value is computed -in O(1) time regardless of the sigma, thanks to the use of integral -images. The algorithm is based on the paper -Agrawal08 -, but instead -of a square, hexagon or octagon it uses an 8-end star shape, hence the name, -consisting of overlapping upright and tilted squares. - -Each keypoint is represented by a tuple -``((x, y), size, response)`` -: - - - - * **x, y** Screen coordinates of the keypoint - - - * **size** feature size, up to ``maxSize`` - - - * **response** approximated laplacian value for the keypoint - - - diff --git a/doc/opencv1/py/highgui.rst b/doc/opencv1/py/highgui.rst deleted file mode 100644 index 1efe615f67..0000000000 --- a/doc/opencv1/py/highgui.rst +++ /dev/null @@ -1,38 +0,0 @@ -************************************* -highgui. High-level GUI and Media I/O -************************************* - - -While OpenCV was designed for use in full-scale -applications and can be used within functionally rich UI frameworks (such as Qt, WinForms or Cocoa) or without any UI at all, sometimes there is a need to try some functionality quickly and visualize the results. This is what the HighGUI module has been designed for. - -It provides easy interface to: - - - - -* - create and manipulate windows that can display images and "remember" their content (no need to handle repaint events from OS) - - - -* - add trackbars to the windows, handle simple mouse events as well as keyboard commmands - - - -* - read and write images to/from disk or memory. - - - -* - read video from camera or file and write video to a file. - - - -.. toctree:: - :maxdepth: 2 - - highgui_user_interface - highgui_reading_and_writing_images_and_video diff --git a/doc/opencv1/py/highgui_reading_and_writing_images_and_video.rst b/doc/opencv1/py/highgui_reading_and_writing_images_and_video.rst deleted file mode 100644 index c8f305633a..0000000000 --- a/doc/opencv1/py/highgui_reading_and_writing_images_and_video.rst +++ /dev/null @@ -1,679 +0,0 @@ -Reading and Writing Images and Video -==================================== - -.. highlight:: python - - - -.. index:: LoadImage - -.. _LoadImage: - -LoadImage ---------- - - - - -.. function:: LoadImage(filename, iscolor=CV_LOAD_IMAGE_COLOR)->None - - Loads an image from a file as an IplImage. - - - - - - - :param filename: Name of file to be loaded. - - :type filename: str - - - :param iscolor: Specific color type of the loaded image: - - * **CV_LOAD_IMAGE_COLOR** the loaded image is forced to be a 3-channel color image - - * **CV_LOAD_IMAGE_GRAYSCALE** the loaded image is forced to be grayscale - - * **CV_LOAD_IMAGE_UNCHANGED** the loaded image will be loaded as is. - - - - :type iscolor: int - - - -The function -``cvLoadImage`` -loads an image from the specified file and returns the pointer to the loaded image. Currently the following file formats are supported: - - - - -* - Windows bitmaps - BMP, DIB - - -* - JPEG files - JPEG, JPG, JPE - - -* - Portable Network Graphics - PNG - - -* - Portable image format - PBM, PGM, PPM - - -* - Sun rasters - SR, RAS - - -* - TIFF files - TIFF, TIF - - -Note that in the current implementation the alpha channel, if any, is stripped from the output image, e.g. 4-channel RGBA image will be loaded as RGB. - - -.. index:: LoadImageM - -.. _LoadImageM: - -LoadImageM ----------- - - - - -.. function:: LoadImageM(filename, iscolor=CV_LOAD_IMAGE_COLOR)->None - - Loads an image from a file as a CvMat. - - - - - - - :param filename: Name of file to be loaded. - - :type filename: str - - - :param iscolor: Specific color type of the loaded image: - - * **CV_LOAD_IMAGE_COLOR** the loaded image is forced to be a 3-channel color image - - * **CV_LOAD_IMAGE_GRAYSCALE** the loaded image is forced to be grayscale - - * **CV_LOAD_IMAGE_UNCHANGED** the loaded image will be loaded as is. - - - - :type iscolor: int - - - -The function -``cvLoadImageM`` -loads an image from the specified file and returns the pointer to the loaded image. -urrently the following file formats are supported: - - - - -* - Windows bitmaps - BMP, DIB - - -* - JPEG files - JPEG, JPG, JPE - - -* - Portable Network Graphics - PNG - - -* - Portable image format - PBM, PGM, PPM - - -* - Sun rasters - SR, RAS - - -* - TIFF files - TIFF, TIF - - -Note that in the current implementation the alpha channel, if any, is stripped from the output image, e.g. 4-channel RGBA image will be loaded as RGB. - - -.. index:: SaveImage - -.. _SaveImage: - -SaveImage ---------- - - - - -.. function:: SaveImage(filename,image)-> None - - Saves an image to a specified file. - - - - - - - :param filename: Name of the file. - - :type filename: str - - - :param image: Image to be saved. - - :type image: :class:`CvArr` - - - -The function -``cvSaveImage`` -saves the image to the specified file. The image format is chosen based on the -``filename`` -extension, see -:ref:`LoadImage` -. Only 8-bit single-channel or 3-channel (with 'BGR' channel order) images can be saved using this function. If the format, depth or channel order is different, use -``cvCvtScale`` -and -``cvCvtColor`` -to convert it before saving, or use universal -``cvSave`` -to save the image to XML or YAML format. - - - -.. index:: CvCapture - -.. _CvCapture: - -CvCapture ---------- - - - -.. class:: CvCapture - - - -Video capturing structure. - -The structure -``CvCapture`` -does not have a public interface and is used only as a parameter for video capturing functions. - - -.. index:: CaptureFromCAM - -.. _CaptureFromCAM: - -CaptureFromCAM --------------- - - - - -.. function:: CaptureFromCAM(index) -> CvCapture - - Initializes capturing a video from a camera. - - - - - - - :param index: Index of the camera to be used. If there is only one camera or it does not matter what camera is used -1 may be passed. - - :type index: int - - - -The function -``cvCaptureFromCAM`` -allocates and initializes the CvCapture structure for reading a video stream from the camera. Currently two camera interfaces can be used on Windows: Video for Windows (VFW) and Matrox Imaging Library (MIL); and two on Linux: V4L and FireWire (IEEE1394). - -To release the structure, use -:ref:`ReleaseCapture` -. - - - -.. index:: CaptureFromFile - -.. _CaptureFromFile: - -CaptureFromFile ---------------- - - - - -.. function:: CaptureFromFile(filename) -> CvCapture - - Initializes capturing a video from a file. - - - - - - - :param filename: Name of the video file. - - :type filename: str - - - -The function -``cvCaptureFromFile`` -allocates and initializes the CvCapture structure for reading the video stream from the specified file. Which codecs and file formats are supported depends on the back end library. On Windows HighGui uses Video for Windows (VfW), on Linux ffmpeg is used and on Mac OS X the back end is QuickTime. See VideoCodecs for some discussion on what to expect and how to prepare your video files. - -After the allocated structure is not used any more it should be released by the -:ref:`ReleaseCapture` -function. - - -.. index:: GetCaptureProperty - -.. _GetCaptureProperty: - -GetCaptureProperty ------------------- - - - - -.. function:: GetCaptureProperty(capture, property_id)->double - - Gets video capturing properties. - - - - - - - :param capture: video capturing structure. - - :type capture: :class:`CvCapture` - - - :param property_id: Property identifier. Can be one of the following: - - :type property_id: int - - - - - * **CV_CAP_PROP_POS_MSEC** Film current position in milliseconds or video capture timestamp - - - * **CV_CAP_PROP_POS_FRAMES** 0-based index of the frame to be decoded/captured next - - - * **CV_CAP_PROP_POS_AVI_RATIO** Relative position of the video file (0 - start of the film, 1 - end of the film) - - - * **CV_CAP_PROP_FRAME_WIDTH** Width of the frames in the video stream - - - * **CV_CAP_PROP_FRAME_HEIGHT** Height of the frames in the video stream - - - * **CV_CAP_PROP_FPS** Frame rate - - - * **CV_CAP_PROP_FOURCC** 4-character code of codec - - - * **CV_CAP_PROP_FRAME_COUNT** Number of frames in the video file - - - * **CV_CAP_PROP_FORMAT** The format of the Mat objects returned by retrieve() - - - * **CV_CAP_PROP_MODE** A backend-specific value indicating the current capture mode - - - * **CV_CAP_PROP_BRIGHTNESS** Brightness of the image (only for cameras) - - - * **CV_CAP_PROP_CONTRAST** Contrast of the image (only for cameras) - - - * **CV_CAP_PROP_SATURATION** Saturation of the image (only for cameras) - - - * **CV_CAP_PROP_HUE** Hue of the image (only for cameras) - - - * **CV_CAP_PROP_GAIN** Gain of the image (only for cameras) - - - * **CV_CAP_PROP_EXPOSURE** Exposure (only for cameras) - - - * **CV_CAP_PROP_CONVERT_RGB** Boolean flags indicating whether images should be converted to RGB - - - * **CV_CAP_PROP_WHITE_BALANCE** Currently unsupported - - - * **CV_CAP_PROP_RECTIFICATION** TOWRITE (note: only supported by DC1394 v 2.x backend currently) - - - - - -The function -``cvGetCaptureProperty`` -retrieves the specified property of the camera or video file. - - -.. index:: GrabFrame - -.. _GrabFrame: - -GrabFrame ---------- - - - - -.. function:: GrabFrame(capture) -> int - - Grabs the frame from a camera or file. - - - - - - - :param capture: video capturing structure. - - :type capture: :class:`CvCapture` - - - -The function -``cvGrabFrame`` -grabs the frame from a camera or file. The grabbed frame is stored internally. The purpose of this function is to grab the frame -*quickly* -so that syncronization can occur if it has to read from several cameras simultaneously. The grabbed frames are not exposed because they may be stored in a compressed format (as defined by the camera/driver). To retrieve the grabbed frame, -:ref:`RetrieveFrame` -should be used. - - - -.. index:: QueryFrame - -.. _QueryFrame: - -QueryFrame ----------- - - - - -.. function:: QueryFrame(capture) -> iplimage - - Grabs and returns a frame from a camera or file. - - - - - - - :param capture: video capturing structure. - - :type capture: :class:`CvCapture` - - - -The function -``cvQueryFrame`` -grabs a frame from a camera or video file, decompresses it and returns it. This function is just a combination of -:ref:`GrabFrame` -and -:ref:`RetrieveFrame` -, but in one call. The returned image should not be released or modified by the user. In the event of an error, the return value may be NULL. - - -.. index:: RetrieveFrame - -.. _RetrieveFrame: - -RetrieveFrame -------------- - - - - -.. function:: RetrieveFrame(capture) -> iplimage - - Gets the image grabbed with cvGrabFrame. - - - - - - - :param capture: video capturing structure. - - :type capture: :class:`CvCapture` - - - -The function -``cvRetrieveFrame`` -returns the pointer to the image grabbed with the -:ref:`GrabFrame` -function. The returned image should not be released or modified by the user. In the event of an error, the return value may be NULL. - - - -.. index:: SetCaptureProperty - -.. _SetCaptureProperty: - -SetCaptureProperty ------------------- - - - - -.. function:: SetCaptureProperty(capture, property_id,value)->None - - Sets video capturing properties. - - - - - - - :param capture: video capturing structure. - - :type capture: :class:`CvCapture` - - - :param property_id: property identifier. Can be one of the following: - - :type property_id: int - - - - - * **CV_CAP_PROP_POS_MSEC** Film current position in milliseconds or video capture timestamp - - - * **CV_CAP_PROP_POS_FRAMES** 0-based index of the frame to be decoded/captured next - - - * **CV_CAP_PROP_POS_AVI_RATIO** Relative position of the video file (0 - start of the film, 1 - end of the film) - - - * **CV_CAP_PROP_FRAME_WIDTH** Width of the frames in the video stream - - - * **CV_CAP_PROP_FRAME_HEIGHT** Height of the frames in the video stream - - - * **CV_CAP_PROP_FPS** Frame rate - - - * **CV_CAP_PROP_FOURCC** 4-character code of codec - - - * **CV_CAP_PROP_FRAME_COUNT** Number of frames in the video file - - - * **CV_CAP_PROP_FORMAT** The format of the Mat objects returned by retrieve() - - - * **CV_CAP_PROP_MODE** A backend-specific value indicating the current capture mode - - - * **CV_CAP_PROP_BRIGHTNESS** Brightness of the image (only for cameras) - - - * **CV_CAP_PROP_CONTRAST** Contrast of the image (only for cameras) - - - * **CV_CAP_PROP_SATURATION** Saturation of the image (only for cameras) - - - * **CV_CAP_PROP_HUE** Hue of the image (only for cameras) - - - * **CV_CAP_PROP_GAIN** Gain of the image (only for cameras) - - - * **CV_CAP_PROP_EXPOSURE** Exposure (only for cameras) - - - * **CV_CAP_PROP_CONVERT_RGB** Boolean flags indicating whether images should be converted to RGB - - - * **CV_CAP_PROP_WHITE_BALANCE** Currently unsupported - - - * **CV_CAP_PROP_RECTIFICATION** TOWRITE (note: only supported by DC1394 v 2.x backend currently) - - - - - :param value: value of the property. - - :type value: float - - - -The function -``cvSetCaptureProperty`` -sets the specified property of video capturing. Currently the function supports only video files: -``CV_CAP_PROP_POS_MSEC, CV_CAP_PROP_POS_FRAMES, CV_CAP_PROP_POS_AVI_RATIO`` -. - -NB This function currently does nothing when using the latest CVS download on linux with FFMPEG (the function contents are hidden if 0 is used and returned). - - - -.. index:: CreateVideoWriter - -.. _CreateVideoWriter: - -CreateVideoWriter ------------------ - - - - -.. function:: CreateVideoWriter(filename, fourcc, fps, frame_size, is_color) -> CvVideoWriter - - Creates the video file writer. - - - - - - - :param filename: Name of the output video file. - - :type filename: str - - - :param fourcc: 4-character code of codec used to compress the frames. For example, ``CV_FOURCC('P','I','M,'1')`` is a MPEG-1 codec, ``CV_FOURCC('M','J','P','G')`` is a motion-jpeg codec etc. - Under Win32 it is possible to pass -1 in order to choose compression method and additional compression parameters from dialog. Under Win32 if 0 is passed while using an avi filename it will create a video writer that creates an uncompressed avi file. - - :type fourcc: int - - - :param fps: Framerate of the created video stream. - - :type fps: float - - - :param frame_size: Size of the video frames. - - :type frame_size: :class:`CvSize` - - - :param is_color: If it is not zero, the encoder will expect and encode color frames, otherwise it will work with grayscale frames (the flag is currently supported on Windows only). - - :type is_color: int - - - -The function -``cvCreateVideoWriter`` -creates the video writer structure. - -Which codecs and file formats are supported depends on the back end library. On Windows HighGui uses Video for Windows (VfW), on Linux ffmpeg is used and on Mac OS X the back end is QuickTime. See VideoCodecs for some discussion on what to expect. - - - -.. index:: WriteFrame - -.. _WriteFrame: - -WriteFrame ----------- - - - - -.. function:: WriteFrame(writer, image)->int - - Writes a frame to a video file. - - - - - - - :param writer: Video writer structure - - :type writer: :class:`CvVideoWriter` - - - :param image: The written frame - - :type image: :class:`IplImage` - - - -The function -``cvWriteFrame`` -writes/appends one frame to a video file. - diff --git a/doc/opencv1/py/highgui_user_interface.rst b/doc/opencv1/py/highgui_user_interface.rst deleted file mode 100644 index 0ed93c1a1d..0000000000 --- a/doc/opencv1/py/highgui_user_interface.rst +++ /dev/null @@ -1,576 +0,0 @@ -User Interface -============== - -.. highlight:: python - - - -.. index:: CreateTrackbar - -.. _CreateTrackbar: - -CreateTrackbar --------------- - - - - -.. function:: CreateTrackbar(trackbarName, windowName, value, count, onChange) -> None - - Creates a trackbar and attaches it to the specified window - - - - - - - :param trackbarName: Name of the created trackbar. - - :type trackbarName: str - - - :param windowName: Name of the window which will be used as a parent for created trackbar. - - :type windowName: str - - - :param value: Initial value for the slider position, between 0 and ``count`` . - - :type value: int - - - :param count: Maximal position of the slider. Minimal position is always 0. - - :type count: int - - - :param onChange: - OpenCV calls ``onChange`` every time the slider changes position. - OpenCV will call it as ``func(x)`` where ``x`` is the new position of the slider. - - :type onChange: :class:`PyCallableObject` - - - -The function -``cvCreateTrackbar`` -creates a trackbar (a.k.a. slider or range control) with the specified name and range, assigns a variable to be syncronized with trackbar position and specifies a callback function to be called on trackbar position change. The created trackbar is displayed on the top of the given window. -\ -\ -**[Qt Backend Only]** -qt-specific details: - - - - * **windowName** Name of the window which will be used as a parent for created trackbar. Can be NULL if the trackbar should be attached to the control panel. - - - -The created trackbar is displayed at the bottom of the given window if -*windowName* -is correctly provided, or displayed on the control panel if -*windowName* -is NULL. - -By clicking on the label of each trackbar, it is possible to edit the trackbar's value manually for a more accurate control of it. - - -.. index:: DestroyAllWindows - -.. _DestroyAllWindows: - -DestroyAllWindows ------------------ - - - - -.. function:: DestroyAllWindows()-> None - - Destroys all of the HighGUI windows. - - - -The function -``cvDestroyAllWindows`` -destroys all of the opened HighGUI windows. - - -.. index:: DestroyWindow - -.. _DestroyWindow: - -DestroyWindow -------------- - - - - -.. function:: DestroyWindow(name)-> None - - Destroys a window. - - - - - - - :param name: Name of the window to be destroyed. - - :type name: str - - - -The function -``cvDestroyWindow`` -destroys the window with the given name. - - -.. index:: GetTrackbarPos - -.. _GetTrackbarPos: - -GetTrackbarPos --------------- - - - - -.. function:: GetTrackbarPos(trackbarName,windowName)-> None - - Returns the trackbar position. - - - - - - - :param trackbarName: Name of the trackbar. - - :type trackbarName: str - - - :param windowName: Name of the window which is the parent of the trackbar. - - :type windowName: str - - - -The function -``cvGetTrackbarPos`` -returns the current position of the specified trackbar. -\ -\ -**[Qt Backend Only]** -qt-specific details: - - - - * **windowName** Name of the window which is the parent of the trackbar. Can be NULL if the trackbar is attached to the control panel. - - - - -.. index:: MoveWindow - -.. _MoveWindow: - -MoveWindow ----------- - - - - -.. function:: MoveWindow(name,x,y)-> None - - Sets the position of the window. - - - - - - - :param name: Name of the window to be moved. - - :type name: str - - - :param x: New x coordinate of the top-left corner - - :type x: int - - - :param y: New y coordinate of the top-left corner - - :type y: int - - - -The function -``cvMoveWindow`` -changes the position of the window. - - -.. index:: NamedWindow - -.. _NamedWindow: - -NamedWindow ------------ - - - - -.. function:: NamedWindow(name,flags=CV_WINDOW_AUTOSIZE)-> None - - Creates a window. - - - - - - - :param name: Name of the window in the window caption that may be used as a window identifier. - - :type name: str - - - :param flags: Flags of the window. Currently the only supported flag is ``CV_WINDOW_AUTOSIZE`` . If this is set, window size is automatically adjusted to fit the displayed image (see :ref:`ShowImage` ), and the user can not change the window size manually. - - :type flags: int - - - -The function -``cvNamedWindow`` -creates a window which can be used as a placeholder for images and trackbars. Created windows are referred to by their names. - -If a window with the same name already exists, the function does nothing. -\ -\ -**[Qt Backend Only]** -qt-specific details: - - - - * **flags** Flags of the window. Currently the supported flags are: - - - * **CV_WINDOW_NORMAL or CV_WINDOW_AUTOSIZE:** ``CV_WINDOW_NORMAL`` let the user resize the window, whereas ``CV_WINDOW_AUTOSIZE`` adjusts automatically the window's size to fit the displayed image (see :ref:`ShowImage` ), and the user can not change the window size manually. - - - * **CV_WINDOW_FREERATIO or CV_WINDOW_KEEPRATIO:** ``CV_WINDOW_FREERATIO`` adjust the image without respect the its ration, whereas ``CV_WINDOW_KEEPRATIO`` keep the image's ratio. - - - * **CV_GUI_NORMAL or CV_GUI_EXPANDED:** ``CV_GUI_NORMAL`` is the old way to draw the window without statusbar and toolbar, whereas ``CV_GUI_EXPANDED`` is the new enhance GUI. - - - - This parameter is optional. The default flags set for a new window are ``CV_WINDOW_AUTOSIZE`` , ``CV_WINDOW_KEEPRATIO`` , and ``CV_GUI_EXPANDED`` . - - However, if you want to modify the flags, you can combine them using OR operator, ie: - - - :: - - - - cvNamedWindow( ``myWindow'', ``CV_WINDOW_NORMAL`` textbar ``CV_GUI_NORMAL`` ); - - - - .. - - - - -.. index:: ResizeWindow - -.. _ResizeWindow: - -ResizeWindow ------------- - - - - -.. function:: ResizeWindow(name,width,height)-> None - - Sets the window size. - - - - - - - :param name: Name of the window to be resized. - - :type name: str - - - :param width: New width - - :type width: int - - - :param height: New height - - :type height: int - - - -The function -``cvResizeWindow`` -changes the size of the window. - - -.. index:: SetMouseCallback - -.. _SetMouseCallback: - -SetMouseCallback ----------------- - - - - -.. function:: SetMouseCallback(windowName, onMouse, param) -> None - - Assigns callback for mouse events. - - - - - - - :param windowName: Name of the window. - - :type windowName: str - - - :param onMouse: Callable to be called every time a mouse event occurs in the specified window. This callable should have signature `` Foo(event, x, y, flags, param)-> None `` - where ``event`` is one of ``CV_EVENT_*`` , ``x`` and ``y`` are the coordinates of the mouse pointer in image coordinates (not window coordinates), ``flags`` is a combination of ``CV_EVENT_FLAG_*`` , and ``param`` is a user-defined parameter passed to the ``cvSetMouseCallback`` function call. - - :type onMouse: :class:`PyCallableObject` - - - :param param: User-defined parameter to be passed to the callback function. - - :type param: object - - - -The function -``cvSetMouseCallback`` -sets the callback function for mouse events occuring within the specified window. - -The -``event`` -parameter is one of: - - - - - * **CV_EVENT_MOUSEMOVE** Mouse movement - - - * **CV_EVENT_LBUTTONDOWN** Left button down - - - * **CV_EVENT_RBUTTONDOWN** Right button down - - - * **CV_EVENT_MBUTTONDOWN** Middle button down - - - * **CV_EVENT_LBUTTONUP** Left button up - - - * **CV_EVENT_RBUTTONUP** Right button up - - - * **CV_EVENT_MBUTTONUP** Middle button up - - - * **CV_EVENT_LBUTTONDBLCLK** Left button double click - - - * **CV_EVENT_RBUTTONDBLCLK** Right button double click - - - * **CV_EVENT_MBUTTONDBLCLK** Middle button double click - - - -The -``flags`` -parameter is a combination of : - - - - - * **CV_EVENT_FLAG_LBUTTON** Left button pressed - - - * **CV_EVENT_FLAG_RBUTTON** Right button pressed - - - * **CV_EVENT_FLAG_MBUTTON** Middle button pressed - - - * **CV_EVENT_FLAG_CTRLKEY** Control key pressed - - - * **CV_EVENT_FLAG_SHIFTKEY** Shift key pressed - - - * **CV_EVENT_FLAG_ALTKEY** Alt key pressed - - - - -.. index:: SetTrackbarPos - -.. _SetTrackbarPos: - -SetTrackbarPos --------------- - - - - -.. function:: SetTrackbarPos(trackbarName,windowName,pos)-> None - - Sets the trackbar position. - - - - - - - :param trackbarName: Name of the trackbar. - - :type trackbarName: str - - - :param windowName: Name of the window which is the parent of trackbar. - - :type windowName: str - - - :param pos: New position. - - :type pos: int - - - -The function -``cvSetTrackbarPos`` -sets the position of the specified trackbar. -\ -\ -**[Qt Backend Only]** -qt-specific details: - - - - * **windowName** Name of the window which is the parent of trackbar. Can be NULL if the trackbar is attached to the control panel. - - - - -.. index:: ShowImage - -.. _ShowImage: - -ShowImage ---------- - - - - -.. function:: ShowImage(name,image)-> None - - Displays the image in the specified window - - - - - - - :param name: Name of the window. - - :type name: str - - - :param image: Image to be shown. - - :type image: :class:`CvArr` - - - -The function -``cvShowImage`` -displays the image in the specified window. If the window was created with the -``CV_WINDOW_AUTOSIZE`` -flag then the image is shown with its original size, otherwise the image is scaled to fit in the window. The function may scale the image, depending on its depth: - - - - -* - If the image is 8-bit unsigned, it is displayed as is. - - - -* - If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range [0,255*256] is mapped to [0,255]. - - - -* - If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255]. - - - -.. index:: WaitKey - -.. _WaitKey: - -WaitKey -------- - - - - -.. function:: WaitKey(delay=0)-> int - - Waits for a pressed key. - - - - - - - :param delay: Delay in milliseconds. - - :type delay: int - - - -The function -``cvWaitKey`` -waits for key event infinitely ( -:math:`\texttt{delay} <= 0` -) or for -``delay`` -milliseconds. Returns the code of the pressed key or -1 if no key was pressed before the specified time had elapsed. - -**Note:** -This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing, unless HighGUI is used within some environment that takes care of event processing. -\ -\ -**[Qt Backend Only]** -qt-specific details: -With this current Qt implementation, this is the only way to process event such as repaint for the windows, and so on -ldots diff --git a/doc/opencv1/py/imgproc.rst b/doc/opencv1/py/imgproc.rst deleted file mode 100644 index 84801cb04e..0000000000 --- a/doc/opencv1/py/imgproc.rst +++ /dev/null @@ -1,18 +0,0 @@ -************************* -imgproc. Image Processing -************************* - - - -.. toctree:: - :maxdepth: 2 - - imgproc_histograms - imgproc_image_filtering - imgproc_geometric_image_transformations - imgproc_miscellaneous_image_transformations - imgproc_structural_analysis_and_shape_descriptors - imgproc_planar_subdivisions - imgproc_motion_analysis_and_object_tracking - imgproc_feature_detection - imgproc_object_detection diff --git a/doc/opencv1/py/imgproc_feature_detection.rst b/doc/opencv1/py/imgproc_feature_detection.rst deleted file mode 100644 index 86160782f2..0000000000 --- a/doc/opencv1/py/imgproc_feature_detection.rst +++ /dev/null @@ -1,628 +0,0 @@ -Feature Detection -================= - -.. highlight:: python - - - -.. index:: Canny - -.. _Canny: - -Canny ------ - - - - -.. function:: Canny(image,edges,threshold1,threshold2,aperture_size=3)-> None - - Implements the Canny algorithm for edge detection. - - - - - - - :param image: Single-channel input image - - :type image: :class:`CvArr` - - - :param edges: Single-channel image to store the edges found by the function - - :type edges: :class:`CvArr` - - - :param threshold1: The first threshold - - :type threshold1: float - - - :param threshold2: The second threshold - - :type threshold2: float - - - :param aperture_size: Aperture parameter for the Sobel operator (see :ref:`Sobel` ) - - :type aperture_size: int - - - -The function finds the edges on the input image -``image`` -and marks them in the output image -``edges`` -using the Canny algorithm. The smallest value between -``threshold1`` -and -``threshold2`` -is used for edge linking, the largest value is used to find the initial segments of strong edges. - - -.. index:: CornerEigenValsAndVecs - -.. _CornerEigenValsAndVecs: - -CornerEigenValsAndVecs ----------------------- - - - - -.. function:: CornerEigenValsAndVecs(image,eigenvv,blockSize,aperture_size=3)-> None - - Calculates eigenvalues and eigenvectors of image blocks for corner detection. - - - - - - - :param image: Input image - - :type image: :class:`CvArr` - - - :param eigenvv: Image to store the results. It must be 6 times wider than the input image - - :type eigenvv: :class:`CvArr` - - - :param blockSize: Neighborhood size (see discussion) - - :type blockSize: int - - - :param aperture_size: Aperture parameter for the Sobel operator (see :ref:`Sobel` ) - - :type aperture_size: int - - - -For every pixel, the function -``cvCornerEigenValsAndVecs`` -considers a -:math:`\texttt{blockSize} \times \texttt{blockSize}` -neigborhood S(p). It calcualtes the covariation matrix of derivatives over the neigborhood as: - - - -.. math:: - - M = \begin{bmatrix} \sum _{S(p)}(dI/dx)^2 & \sum _{S(p)}(dI/dx \cdot dI/dy)^2 \\ \sum _{S(p)}(dI/dx \cdot dI/dy)^2 & \sum _{S(p)}(dI/dy)^2 \end{bmatrix} - - -After that it finds eigenvectors and eigenvalues of the matrix and stores them into destination image in form -:math:`(\lambda_1, \lambda_2, x_1, y_1, x_2, y_2)` -where - - - - -* :math:`\lambda_1, \lambda_2` - are the eigenvalues of - :math:`M` - ; not sorted - - -* :math:`x_1, y_1` - are the eigenvectors corresponding to - :math:`\lambda_1` - - -* :math:`x_2, y_2` - are the eigenvectors corresponding to - :math:`\lambda_2` - - - -.. index:: CornerHarris - -.. _CornerHarris: - -CornerHarris ------------- - - - - -.. function:: CornerHarris(image,harris_dst,blockSize,aperture_size=3,k=0.04)-> None - - Harris edge detector. - - - - - - - :param image: Input image - - :type image: :class:`CvArr` - - - :param harris_dst: Image to store the Harris detector responses. Should have the same size as ``image`` - - :type harris_dst: :class:`CvArr` - - - :param blockSize: Neighborhood size (see the discussion of :ref:`CornerEigenValsAndVecs` ) - - :type blockSize: int - - - :param aperture_size: Aperture parameter for the Sobel operator (see :ref:`Sobel` ). - - :type aperture_size: int - - - :param k: Harris detector free parameter. See the formula below - - :type k: float - - - -The function runs the Harris edge detector on the image. Similarly to -:ref:`CornerMinEigenVal` -and -:ref:`CornerEigenValsAndVecs` -, for each pixel it calculates a -:math:`2\times2` -gradient covariation matrix -:math:`M` -over a -:math:`\texttt{blockSize} \times \texttt{blockSize}` -neighborhood. Then, it stores - - - -.. math:: - - det(M) - k \, trace(M)^2 - - -to the destination image. Corners in the image can be found as the local maxima of the destination image. - - -.. index:: CornerMinEigenVal - -.. _CornerMinEigenVal: - -CornerMinEigenVal ------------------ - - - - -.. function:: CornerMinEigenVal(image,eigenval,blockSize,aperture_size=3)-> None - - Calculates the minimal eigenvalue of gradient matrices for corner detection. - - - - - - - :param image: Input image - - :type image: :class:`CvArr` - - - :param eigenval: Image to store the minimal eigenvalues. Should have the same size as ``image`` - - :type eigenval: :class:`CvArr` - - - :param blockSize: Neighborhood size (see the discussion of :ref:`CornerEigenValsAndVecs` ) - - :type blockSize: int - - - :param aperture_size: Aperture parameter for the Sobel operator (see :ref:`Sobel` ). - - :type aperture_size: int - - - -The function is similar to -:ref:`CornerEigenValsAndVecs` -but it calculates and stores only the minimal eigen value of derivative covariation matrix for every pixel, i.e. -:math:`min(\lambda_1, \lambda_2)` -in terms of the previous function. - - -.. index:: FindCornerSubPix - -.. _FindCornerSubPix: - -FindCornerSubPix ----------------- - - - - -.. function:: FindCornerSubPix(image,corners,win,zero_zone,criteria)-> corners - - Refines the corner locations. - - - - - - - :param image: Input image - - :type image: :class:`CvArr` - - - :param corners: Initial coordinates of the input corners as a list of (x, y) pairs - - :type corners: sequence of (float, float) - - - :param win: Half of the side length of the search window. For example, if ``win`` =(5,5), then a :math:`5*2+1 \times 5*2+1 = 11 \times 11` search window would be used - - :type win: :class:`CvSize` - - - :param zero_zone: Half of the size of the dead region in the middle of the search zone over which the summation in the formula below is not done. It is used sometimes to avoid possible singularities of the autocorrelation matrix. The value of (-1,-1) indicates that there is no such size - - :type zero_zone: :class:`CvSize` - - - :param criteria: Criteria for termination of the iterative process of corner refinement. That is, the process of corner position refinement stops either after a certain number of iterations or when a required accuracy is achieved. The ``criteria`` may specify either of or both the maximum number of iteration and the required accuracy - - :type criteria: :class:`CvTermCriteria` - - - -The function iterates to find the sub-pixel accurate location of corners, or radial saddle points, as shown in on the picture below. -It returns the refined coordinates as a list of (x, y) pairs. - - -.. image:: ../pics/cornersubpix.png - - - -Sub-pixel accurate corner locator is based on the observation that every vector from the center -:math:`q` -to a point -:math:`p` -located within a neighborhood of -:math:`q` -is orthogonal to the image gradient at -:math:`p` -subject to image and measurement noise. Consider the expression: - - - -.. math:: - - \epsilon _i = {DI_{p_i}}^T \cdot (q - p_i) - - -where -:math:`{DI_{p_i}}` -is the image gradient at the one of the points -:math:`p_i` -in a neighborhood of -:math:`q` -. The value of -:math:`q` -is to be found such that -:math:`\epsilon_i` -is minimized. A system of equations may be set up with -:math:`\epsilon_i` -set to zero: - - - -.. math:: - - \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T) q = \sum _i(DI_{p_i} \cdot {DI_{p_i}}^T \cdot p_i) - - -where the gradients are summed within a neighborhood ("search window") of -:math:`q` -. Calling the first gradient term -:math:`G` -and the second gradient term -:math:`b` -gives: - - - -.. math:: - - q = G^{-1} \cdot b - - -The algorithm sets the center of the neighborhood window at this new center -:math:`q` -and then iterates until the center keeps within a set threshold. - - -.. index:: GoodFeaturesToTrack - -.. _GoodFeaturesToTrack: - -GoodFeaturesToTrack -------------------- - - - - -.. function:: GoodFeaturesToTrack(image,eigImage,tempImage,cornerCount,qualityLevel,minDistance,mask=NULL,blockSize=3,useHarris=0,k=0.04)-> corners - - Determines strong corners on an image. - - - - - - - :param image: The source 8-bit or floating-point 32-bit, single-channel image - - :type image: :class:`CvArr` - - - :param eigImage: Temporary floating-point 32-bit image, the same size as ``image`` - - :type eigImage: :class:`CvArr` - - - :param tempImage: Another temporary image, the same size and format as ``eigImage`` - - :type tempImage: :class:`CvArr` - - - :param cornerCount: number of corners to detect - - :type cornerCount: int - - - :param qualityLevel: Multiplier for the max/min eigenvalue; specifies the minimal accepted quality of image corners - - :type qualityLevel: float - - - :param minDistance: Limit, specifying the minimum possible distance between the returned corners; Euclidian distance is used - - :type minDistance: float - - - :param mask: Region of interest. The function selects points either in the specified region or in the whole image if the mask is NULL - - :type mask: :class:`CvArr` - - - :param blockSize: Size of the averaging block, passed to the underlying :ref:`CornerMinEigenVal` or :ref:`CornerHarris` used by the function - - :type blockSize: int - - - :param useHarris: If nonzero, Harris operator ( :ref:`CornerHarris` ) is used instead of default :ref:`CornerMinEigenVal` - - :type useHarris: int - - - :param k: Free parameter of Harris detector; used only if ( :math:`\texttt{useHarris} != 0` ) - - :type k: float - - - -The function finds the corners with big eigenvalues in the image. The function first calculates the minimal -eigenvalue for every source image pixel using the -:ref:`CornerMinEigenVal` -function and stores them in -``eigImage`` -. Then it performs -non-maxima suppression (only the local maxima in -:math:`3\times 3` -neighborhood -are retained). The next step rejects the corners with the minimal -eigenvalue less than -:math:`\texttt{qualityLevel} \cdot max(\texttt{eigImage}(x,y))` -. -Finally, the function ensures that the distance between any two corners is not smaller than -``minDistance`` -. The weaker corners (with a smaller min eigenvalue) that are too close to the stronger corners are rejected. - -Note that the if the function is called with different values -``A`` -and -``B`` -of the parameter -``qualityLevel`` -, and -``A`` -> {B}, the array of returned corners with -``qualityLevel=A`` -will be the prefix of the output corners array with -``qualityLevel=B`` -. - - -.. index:: HoughLines2 - -.. _HoughLines2: - -HoughLines2 ------------ - - - - -.. function:: HoughLines2(image,storage,method,rho,theta,threshold,param1=0,param2=0)-> lines - - Finds lines in a binary image using a Hough transform. - - - - - - - :param image: The 8-bit, single-channel, binary source image. In the case of a probabilistic method, the image is modified by the function - - :type image: :class:`CvArr` - - - :param storage: The storage for the lines that are detected. It can - be a memory storage (in this case a sequence of lines is created in - the storage and returned by the function) or single row/single column - matrix (CvMat*) of a particular type (see below) to which the lines' - parameters are written. The matrix header is modified by the function - so its ``cols`` or ``rows`` will contain the number of lines - detected. If ``storage`` is a matrix and the actual number - of lines exceeds the matrix size, the maximum possible number of lines - is returned (in the case of standard hough transform the lines are sorted - by the accumulator value) - - :type storage: :class:`CvMemStorage` - - - :param method: The Hough transform variant, one of the following: - - - * **CV_HOUGH_STANDARD** classical or standard Hough transform. Every line is represented by two floating-point numbers :math:`(\rho, \theta)` , where :math:`\rho` is a distance between (0,0) point and the line, and :math:`\theta` is the angle between x-axis and the normal to the line. Thus, the matrix must be (the created sequence will be) of ``CV_32FC2`` type - - - * **CV_HOUGH_PROBABILISTIC** probabilistic Hough transform (more efficient in case if picture contains a few long linear segments). It returns line segments rather than the whole line. Each segment is represented by starting and ending points, and the matrix must be (the created sequence will be) of ``CV_32SC4`` type - - - * **CV_HOUGH_MULTI_SCALE** multi-scale variant of the classical Hough transform. The lines are encoded the same way as ``CV_HOUGH_STANDARD`` - - - - :type method: int - - - :param rho: Distance resolution in pixel-related units - - :type rho: float - - - :param theta: Angle resolution measured in radians - - :type theta: float - - - :param threshold: Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than ``threshold`` - - :type threshold: int - - - :param param1: The first method-dependent parameter: - - - - * For the classical Hough transform it is not used (0). - - - * For the probabilistic Hough transform it is the minimum line length. - - - * For the multi-scale Hough transform it is the divisor for the distance resolution :math:`\rho` . (The coarse distance resolution will be :math:`\rho` and the accurate resolution will be :math:`(\rho / \texttt{param1})` ). - - - :type param1: float - - - :param param2: The second method-dependent parameter: - - - - * For the classical Hough transform it is not used (0). - - - * For the probabilistic Hough transform it is the maximum gap between line segments lying on the same line to treat them as a single line segment (i.e. to join them). - - - * For the multi-scale Hough transform it is the divisor for the angle resolution :math:`\theta` . (The coarse angle resolution will be :math:`\theta` and the accurate resolution will be :math:`(\theta / \texttt{param2})` ). - - - :type param2: float - - - -The function implements a few variants of the Hough transform for line detection. - - -.. index:: PreCornerDetect - -.. _PreCornerDetect: - -PreCornerDetect ---------------- - - - - -.. function:: PreCornerDetect(image,corners,apertureSize=3)-> None - - Calculates the feature map for corner detection. - - - - - - - :param image: Input image - - :type image: :class:`CvArr` - - - :param corners: Image to store the corner candidates - - :type corners: :class:`CvArr` - - - :param apertureSize: Aperture parameter for the Sobel operator (see :ref:`Sobel` ) - - :type apertureSize: int - - - -The function calculates the function - - - -.. math:: - - D_x^2 D_{yy} + D_y^2 D_{xx} - 2 D_x D_y D_{xy} - - -where -:math:`D_?` -denotes one of the first image derivatives and -:math:`D_{??}` -denotes a second image derivative. - -The corners can be found as local maximums of the function below: - -.. include:: ../../python_fragments/precornerdetect.py - :literal: - - diff --git a/doc/opencv1/py/imgproc_geometric_image_transformations.rst b/doc/opencv1/py/imgproc_geometric_image_transformations.rst deleted file mode 100644 index 5c09435db2..0000000000 --- a/doc/opencv1/py/imgproc_geometric_image_transformations.rst +++ /dev/null @@ -1,748 +0,0 @@ -Geometric Image Transformations -=============================== - -.. highlight:: python - - -The functions in this section perform various geometrical transformations of 2D images. That is, they do not change the image content, but deform the pixel grid, and map this deformed grid to the destination image. In fact, to avoid sampling artifacts, the mapping is done in the reverse order, from destination to the source. That is, for each pixel -:math:`(x, y)` -of the destination image, the functions compute coordinates of the corresponding "donor" pixel in the source image and copy the pixel value, that is: - - - -.. math:: - - \texttt{dst} (x,y)= \texttt{src} (f_x(x,y), f_y(x,y)) - - -In the case when the user specifies the forward mapping: -:math:`\left: \texttt{src} \rightarrow \texttt{dst}` -, the OpenCV functions first compute the corresponding inverse mapping: -:math:`\left: \texttt{dst} \rightarrow \texttt{src}` -and then use the above formula. - -The actual implementations of the geometrical transformations, from the most generic -:ref:`Remap` -and to the simplest and the fastest -:ref:`Resize` -, need to solve the 2 main problems with the above formula: - - - - -#. - extrapolation of non-existing pixels. Similarly to the filtering functions, described in the previous section, for some - :math:`(x,y)` - one of - :math:`f_x(x,y)` - or - :math:`f_y(x,y)` - , or they both, may fall outside of the image, in which case some extrapolation method needs to be used. OpenCV provides the same selection of the extrapolation methods as in the filtering functions, but also an additional method - ``BORDER_TRANSPARENT`` - , which means that the corresponding pixels in the destination image will not be modified at all. - - - -#. - interpolation of pixel values. Usually - :math:`f_x(x,y)` - and - :math:`f_y(x,y)` - are floating-point numbers (i.e. - :math:`\left` - can be an affine or perspective transformation, or radial lens distortion correction etc.), so a pixel values at fractional coordinates needs to be retrieved. In the simplest case the coordinates can be just rounded to the nearest integer coordinates and the corresponding pixel used, which is called nearest-neighbor interpolation. However, a better result can be achieved by using more sophisticated - `interpolation methods `_ - , where a polynomial function is fit into some neighborhood of the computed pixel - :math:`(f_x(x,y), f_y(x,y))` - and then the value of the polynomial at - :math:`(f_x(x,y), f_y(x,y))` - is taken as the interpolated pixel value. In OpenCV you can choose between several interpolation methods, see - :ref:`Resize` - . - - - -.. index:: GetRotationMatrix2D - -.. _GetRotationMatrix2D: - -GetRotationMatrix2D -------------------- - - - - -.. function:: GetRotationMatrix2D(center,angle,scale,mapMatrix)-> None - - Calculates the affine matrix of 2d rotation. - - - - - - - :param center: Center of the rotation in the source image - - :type center: :class:`CvPoint2D32f` - - - :param angle: The rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner) - - :type angle: float - - - :param scale: Isotropic scale factor - - :type scale: float - - - :param mapMatrix: Pointer to the destination :math:`2\times 3` matrix - - :type mapMatrix: :class:`CvMat` - - - -The function -``cv2DRotationMatrix`` -calculates the following matrix: - - - -.. math:: - - \begin{bmatrix} \alpha & \beta & (1- \alpha ) \cdot \texttt{center.x} - \beta \cdot \texttt{center.y} \\ - \beta & \alpha & \beta \cdot \texttt{center.x} - (1- \alpha ) \cdot \texttt{center.y} \end{bmatrix} - - -where - - - -.. math:: - - \alpha = \texttt{scale} \cdot cos( \texttt{angle} ), \beta = \texttt{scale} \cdot sin( \texttt{angle} ) - - -The transformation maps the rotation center to itself. If this is not the purpose, the shift should be adjusted. - - -.. index:: GetAffineTransform - -.. _GetAffineTransform: - -GetAffineTransform ------------------- - - - - -.. function:: GetAffineTransform(src,dst,mapMatrix)-> None - - Calculates the affine transform from 3 corresponding points. - - - - - - - :param src: Coordinates of 3 triangle vertices in the source image - - :type src: :class:`CvPoint2D32f` - - - :param dst: Coordinates of the 3 corresponding triangle vertices in the destination image - - :type dst: :class:`CvPoint2D32f` - - - :param mapMatrix: Pointer to the destination :math:`2 \times 3` matrix - - :type mapMatrix: :class:`CvMat` - - - -The function cvGetAffineTransform calculates the matrix of an affine transform such that: - - - -.. math:: - - \begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} - - -where - - - -.. math:: - - dst(i)=(x'_i,y'_i), - src(i)=(x_i, y_i), - i=0,1,2 - - - -.. index:: GetPerspectiveTransform - -.. _GetPerspectiveTransform: - -GetPerspectiveTransform ------------------------ - - - - -.. function:: GetPerspectiveTransform(src,dst,mapMatrix)-> None - - Calculates the perspective transform from 4 corresponding points. - - - - - - - :param src: Coordinates of 4 quadrangle vertices in the source image - - :type src: :class:`CvPoint2D32f` - - - :param dst: Coordinates of the 4 corresponding quadrangle vertices in the destination image - - :type dst: :class:`CvPoint2D32f` - - - :param mapMatrix: Pointer to the destination :math:`3\times 3` matrix - - :type mapMatrix: :class:`CvMat` - - - -The function -``cvGetPerspectiveTransform`` -calculates a matrix of perspective transforms such that: - - - -.. math:: - - \begin{bmatrix} x'_i \\ y'_i \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x_i \\ y_i \\ 1 \end{bmatrix} - - -where - - - -.. math:: - - dst(i)=(x'_i,y'_i), - src(i)=(x_i, y_i), - i=0,1,2,3 - - - -.. index:: GetQuadrangleSubPix - -.. _GetQuadrangleSubPix: - -GetQuadrangleSubPix -------------------- - - - - -.. function:: GetQuadrangleSubPix(src,dst,mapMatrix)-> None - - Retrieves the pixel quadrangle from an image with sub-pixel accuracy. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Extracted quadrangle - - :type dst: :class:`CvArr` - - - :param mapMatrix: The transformation :math:`2 \times 3` matrix :math:`[A|b]` (see the discussion) - - :type mapMatrix: :class:`CvMat` - - - -The function -``cvGetQuadrangleSubPix`` -extracts pixels from -``src`` -at sub-pixel accuracy and stores them to -``dst`` -as follows: - - - -.. math:: - - dst(x, y)= src( A_{11} x' + A_{12} y' + b_1, A_{21} x' + A_{22} y' + b_2) - - -where - - - -.. math:: - - x'=x- \frac{(width(dst)-1)}{2} , - y'=y- \frac{(height(dst)-1)}{2} - - -and - - - -.. math:: - - \texttt{mapMatrix} = \begin{bmatrix} A_{11} & A_{12} & b_1 \\ A_{21} & A_{22} & b_2 \end{bmatrix} - - -The values of pixels at non-integer coordinates are retrieved using bilinear interpolation. When the function needs pixels outside of the image, it uses replication border mode to reconstruct the values. Every channel of multiple-channel images is processed independently. - - - -.. index:: GetRectSubPix - -.. _GetRectSubPix: - -GetRectSubPix -------------- - - - - -.. function:: GetRectSubPix(src,dst,center)-> None - - Retrieves the pixel rectangle from an image with sub-pixel accuracy. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Extracted rectangle - - :type dst: :class:`CvArr` - - - :param center: Floating point coordinates of the extracted rectangle center within the source image. The center must be inside the image - - :type center: :class:`CvPoint2D32f` - - - -The function -``cvGetRectSubPix`` -extracts pixels from -``src`` -: - - - -.. math:: - - dst(x, y) = src(x + \texttt{center.x} - (width( \texttt{dst} )-1)*0.5, y + \texttt{center.y} - (height( \texttt{dst} )-1)*0.5) - - -where the values of the pixels at non-integer coordinates are retrieved -using bilinear interpolation. Every channel of multiple-channel -images is processed independently. While the rectangle center -must be inside the image, parts of the rectangle may be -outside. In this case, the replication border mode is used to get -pixel values beyond the image boundaries. - - - -.. index:: LogPolar - -.. _LogPolar: - -LogPolar --------- - - - - -.. function:: LogPolar(src,dst,center,M,flags=CV_INNER_LINEAR+CV_WARP_FILL_OUTLIERS)-> None - - Remaps an image to log-polar space. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param center: The transformation center; where the output precision is maximal - - :type center: :class:`CvPoint2D32f` - - - :param M: Magnitude scale parameter. See below - - :type M: float - - - :param flags: A combination of interpolation methods and the following optional flags: - - - * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero - - - * **CV_WARP_INVERSE_MAP** See below - - - - :type flags: int - - - -The function -``cvLogPolar`` -transforms the source image using the following transformation: - -Forward transformation ( -``CV_WARP_INVERSE_MAP`` -is not set): - - - -.. math:: - - dst( \phi , \rho ) = src(x,y) - - -Inverse transformation ( -``CV_WARP_INVERSE_MAP`` -is set): - - - -.. math:: - - dst(x,y) = src( \phi , \rho ) - - -where - - - -.. math:: - - \rho = M \cdot \log{\sqrt{x^2 + y^2}} , \phi =atan(y/x) - - -The function emulates the human "foveal" vision and can be used for fast scale and rotation-invariant template matching, for object tracking and so forth. -The function can not operate in-place. - - -.. index:: Remap - -.. _Remap: - -Remap ------ - - - - -.. function:: Remap(src,dst,mapx,mapy,flags=CV_INNER_LINEAR+CV_WARP_FILL_OUTLIERS,fillval=(0,0,0,0))-> None - - Applies a generic geometrical transformation to the image. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param mapx: The map of x-coordinates (CV _ 32FC1 image) - - :type mapx: :class:`CvArr` - - - :param mapy: The map of y-coordinates (CV _ 32FC1 image) - - :type mapy: :class:`CvArr` - - - :param flags: A combination of interpolation method and the following optional flag(s): - - - * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to ``fillval`` - - - - :type flags: int - - - :param fillval: A value used to fill outliers - - :type fillval: :class:`CvScalar` - - - -The function -``cvRemap`` -transforms the source image using the specified map: - - - -.. math:: - - \texttt{dst} (x,y) = \texttt{src} ( \texttt{mapx} (x,y), \texttt{mapy} (x,y)) - - -Similar to other geometrical transformations, some interpolation method (specified by user) is used to extract pixels with non-integer coordinates. -Note that the function can not operate in-place. - - -.. index:: Resize - -.. _Resize: - -Resize ------- - - - - -.. function:: Resize(src,dst,interpolation=CV_INTER_LINEAR)-> None - - Resizes an image. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param interpolation: Interpolation method: - - * **CV_INTER_NN** nearest-neigbor interpolation - - * **CV_INTER_LINEAR** bilinear interpolation (used by default) - - * **CV_INTER_AREA** resampling using pixel area relation. It is the preferred method for image decimation that gives moire-free results. In terms of zooming it is similar to the ``CV_INTER_NN`` method - - * **CV_INTER_CUBIC** bicubic interpolation - - - - :type interpolation: int - - - -The function -``cvResize`` -resizes an image -``src`` -so that it fits exactly into -``dst`` -. If ROI is set, the function considers the ROI as supported. - - - -.. index:: WarpAffine - -.. _WarpAffine: - -WarpAffine ----------- - - - - -.. function:: WarpAffine(src,dst,mapMatrix,flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,fillval=(0,0,0,0))-> None - - Applies an affine transformation to an image. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param mapMatrix: :math:`2\times 3` transformation matrix - - :type mapMatrix: :class:`CvMat` - - - :param flags: A combination of interpolation methods and the following optional flags: - - - * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels; if some of them correspond to outliers in the source image, they are set to ``fillval`` - - - * **CV_WARP_INVERSE_MAP** indicates that ``matrix`` is inversely - transformed from the destination image to the source and, thus, can be used - directly for pixel interpolation. Otherwise, the function finds - the inverse transform from ``mapMatrix`` - - - :type flags: int - - - - - :param fillval: A value used to fill outliers - - :type fillval: :class:`CvScalar` - - - -The function -``cvWarpAffine`` -transforms the source image using the specified matrix: - - - -.. math:: - - dst(x',y') = src(x,y) - - -where - - - -.. math:: - - \begin{matrix} \begin{bmatrix} x' \\ y' \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} & \mbox{if CV\_WARP\_INVERSE\_MAP is not set} \\ \begin{bmatrix} x \\ y \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} & \mbox{otherwise} \end{matrix} - - -The function is similar to -:ref:`GetQuadrangleSubPix` -but they are not exactly the same. -:ref:`WarpAffine` -requires input and output image have the same data type, has larger overhead (so it is not quite suitable for small images) and can leave part of destination image unchanged. While -:ref:`GetQuadrangleSubPix` -may extract quadrangles from 8-bit images into floating-point buffer, has smaller overhead and always changes the whole destination image content. -Note that the function can not operate in-place. - -To transform a sparse set of points, use the -:ref:`Transform` -function from cxcore. - - -.. index:: WarpPerspective - -.. _WarpPerspective: - -WarpPerspective ---------------- - - - - -.. function:: WarpPerspective(src,dst,mapMatrix,flags=CV_INNER_LINEAR+CV_WARP_FILL_OUTLIERS,fillval=(0,0,0,0))-> None - - Applies a perspective transformation to an image. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param mapMatrix: :math:`3\times 3` transformation matrix - - :type mapMatrix: :class:`CvMat` - - - :param flags: A combination of interpolation methods and the following optional flags: - - - * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels; if some of them correspond to outliers in the source image, they are set to ``fillval`` - - - * **CV_WARP_INVERSE_MAP** indicates that ``matrix`` is inversely transformed from the destination image to the source and, thus, can be used directly for pixel interpolation. Otherwise, the function finds the inverse transform from ``mapMatrix`` - - - - :type flags: int - - - :param fillval: A value used to fill outliers - - :type fillval: :class:`CvScalar` - - - -The function -``cvWarpPerspective`` -transforms the source image using the specified matrix: - - - -.. math:: - - \begin{matrix} \begin{bmatrix} x' \\ y' \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} & \mbox{if CV\_WARP\_INVERSE\_MAP is not set} \\ \begin{bmatrix} x \\ y \end{bmatrix} = \texttt{mapMatrix} \cdot \begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} & \mbox{otherwise} \end{matrix} - - -Note that the function can not operate in-place. -For a sparse set of points use the -:ref:`PerspectiveTransform` -function from CxCore. - diff --git a/doc/opencv1/py/imgproc_histograms.rst b/doc/opencv1/py/imgproc_histograms.rst deleted file mode 100644 index 989b4ccb24..0000000000 --- a/doc/opencv1/py/imgproc_histograms.rst +++ /dev/null @@ -1,771 +0,0 @@ -Histograms -========== - -.. highlight:: python - - - -.. index:: CvHistogram - -.. _CvHistogram: - -CvHistogram ------------ - - - -.. class:: CvHistogram - - - -Multi-dimensional histogram. - -A CvHistogram is a multi-dimensional histogram, created by function -:ref:`CreateHist` -. It has an attribute -``bins`` -a -:ref:`CvMatND` -containing the histogram counts. - -.. index:: CalcBackProject - -.. _CalcBackProject: - -CalcBackProject ---------------- - - - - -.. function:: CalcBackProject(image,back_project,hist)-> None - - Calculates the back projection. - - - - - - - :param image: Source images (though you may pass CvMat** as well) - - :type image: sequence of :class:`IplImage` - - - :param back_project: Destination back projection image of the same type as the source images - - :type back_project: :class:`CvArr` - - - :param hist: Histogram - - :type hist: :class:`CvHistogram` - - - -The function calculates the back project of the histogram. For each -tuple of pixels at the same position of all input single-channel images -the function puts the value of the histogram bin, corresponding to the -tuple in the destination image. In terms of statistics, the value of -each output image pixel is the probability of the observed tuple given -the distribution (histogram). For example, to find a red object in the -picture, one may do the following: - - - - - -#. - Calculate a hue histogram for the red object assuming the image contains only this object. The histogram is likely to have a strong maximum, corresponding to red color. - - - -#. - Calculate back projection of a hue plane of input image where the object is searched, using the histogram. Threshold the image. - - - -#. - Find connected components in the resulting picture and choose the right component using some additional criteria, for example, the largest connected component. - - -That is the approximate algorithm of Camshift color object tracker, except for the 3rd step, instead of which CAMSHIFT algorithm is used to locate the object on the back projection given the previous object position. - - -.. index:: CalcBackProjectPatch - -.. _CalcBackProjectPatch: - -CalcBackProjectPatch --------------------- - - - - -.. function:: CalcBackProjectPatch(images,dst,patch_size,hist,method,factor)-> None - - Locates a template within an image by using a histogram comparison. - - - - - - - :param images: Source images (though, you may pass CvMat** as well) - - :type images: sequence of :class:`IplImage` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param patch_size: Size of the patch slid though the source image - - :type patch_size: :class:`CvSize` - - - :param hist: Histogram - - :type hist: :class:`CvHistogram` - - - :param method: Comparison method, passed to :ref:`CompareHist` (see description of that function) - - :type method: int - - - :param factor: Normalization factor for histograms, will affect the normalization scale of the destination image, pass 1 if unsure - - :type factor: float - - - -The function calculates the back projection by comparing histograms of the source image patches with the given histogram. Taking measurement results from some image at each location over ROI creates an array -``image`` -. These results might be one or more of hue, -``x`` -derivative, -``y`` -derivative, Laplacian filter, oriented Gabor filter, etc. Each measurement output is collected into its own separate image. The -``image`` -image array is a collection of these measurement images. A multi-dimensional histogram -``hist`` -is constructed by sampling from the -``image`` -image array. The final histogram is normalized. The -``hist`` -histogram has as many dimensions as the number of elements in -``image`` -array. - -Each new image is measured and then converted into an -``image`` -image array over a chosen ROI. Histograms are taken from this -``image`` -image in an area covered by a "patch" with an anchor at center as shown in the picture below. The histogram is normalized using the parameter -``norm_factor`` -so that it may be compared with -``hist`` -. The calculated histogram is compared to the model histogram; -``hist`` -uses The function -``cvCompareHist`` -with the comparison method= -``method`` -). The resulting output is placed at the location corresponding to the patch anchor in the probability image -``dst`` -. This process is repeated as the patch is slid over the ROI. Iterative histogram update by subtracting trailing pixels covered by the patch and adding newly covered pixels to the histogram can save a lot of operations, though it is not implemented yet. - -Back Project Calculation by Patches - - - -.. image:: ../pics/backprojectpatch.png - - - - -.. index:: CalcHist - -.. _CalcHist: - -CalcHist --------- - - - - -.. function:: CalcHist(image,hist,accumulate=0,mask=NULL)-> None - - Calculates the histogram of image(s). - - - - - - - :param image: Source images (though you may pass CvMat** as well) - - :type image: sequence of :class:`IplImage` - - - :param hist: Pointer to the histogram - - :type hist: :class:`CvHistogram` - - - :param accumulate: Accumulation flag. If it is set, the histogram is not cleared in the beginning. This feature allows user to compute a single histogram from several images, or to update the histogram online - - :type accumulate: int - - - :param mask: The operation mask, determines what pixels of the source images are counted - - :type mask: :class:`CvArr` - - - -The function calculates the histogram of one or more -single-channel images. The elements of a tuple that is used to increment -a histogram bin are taken at the same location from the corresponding -input images. - -.. include:: ../../python_fragments/calchist.py - :literal: - - - -.. index:: CalcProbDensity - -.. _CalcProbDensity: - -CalcProbDensity ---------------- - - - - -.. function:: CalcProbDensity(hist1,hist2,dst_hist,scale=255)-> None - - Divides one histogram by another. - - - - - - - :param hist1: first histogram (the divisor) - - :type hist1: :class:`CvHistogram` - - - :param hist2: second histogram - - :type hist2: :class:`CvHistogram` - - - :param dst_hist: destination histogram - - :type dst_hist: :class:`CvHistogram` - - - :param scale: scale factor for the destination histogram - - :type scale: float - - - -The function calculates the object probability density from the two histograms as: - - - -.. math:: - - \texttt{dist\_hist} (I)= \forkthree{0}{if $\texttt{hist1}(I)=0$}{\texttt{scale}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) > \texttt{hist1}(I)$}{\frac{\texttt{hist2}(I) \cdot \texttt{scale}}{\texttt{hist1}(I)}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) \le \texttt{hist1}(I)$} - - -So the destination histogram bins are within less than -``scale`` -. - - -.. index:: ClearHist - -.. _ClearHist: - -ClearHist ---------- - - - - -.. function:: ClearHist(hist)-> None - - Clears the histogram. - - - - - - - :param hist: Histogram - - :type hist: :class:`CvHistogram` - - - -The function sets all of the histogram bins to 0 in the case of a dense histogram and removes all histogram bins in the case of a sparse array. - - -.. index:: CompareHist - -.. _CompareHist: - -CompareHist ------------ - - - - -.. function:: CompareHist(hist1,hist2,method)->float - - Compares two dense histograms. - - - - - - - :param hist1: The first dense histogram - - :type hist1: :class:`CvHistogram` - - - :param hist2: The second dense histogram - - :type hist2: :class:`CvHistogram` - - - :param method: Comparison method, one of the following: - - - * **CV_COMP_CORREL** Correlation - - - * **CV_COMP_CHISQR** Chi-Square - - - * **CV_COMP_INTERSECT** Intersection - - - * **CV_COMP_BHATTACHARYYA** Bhattacharyya distance - - - - :type method: int - - - -The function compares two dense histograms using the specified method ( -:math:`H_1` -denotes the first histogram, -:math:`H_2` -the second): - - - - - -* Correlation (method=CV\_COMP\_CORREL) - - - .. math:: - - d(H_1,H_2) = \frac{\sum_I (H'_1(I) \cdot H'_2(I))}{\sqrt{\sum_I(H'_1(I)^2) \cdot \sum_I(H'_2(I)^2)}} - - - where - - - .. math:: - - H'_k(I) = \frac{H_k(I) - 1}{N \cdot \sum_J H_k(J)} - - - where N is the number of histogram bins. - - - -* Chi-Square (method=CV\_COMP\_CHISQR) - - - .. math:: - - d(H_1,H_2) = \sum _I \frac{(H_1(I)-H_2(I))^2}{H_1(I)+H_2(I)} - - - - -* Intersection (method=CV\_COMP\_INTERSECT) - - - .. math:: - - d(H_1,H_2) = \sum _I \min (H_1(I), H_2(I)) - - - - -* Bhattacharyya distance (method=CV\_COMP\_BHATTACHARYYA) - - - .. math:: - - d(H_1,H_2) = \sqrt{1 - \sum_I \frac{\sqrt{H_1(I) \cdot H_2(I)}}{ \sqrt{ \sum_I H_1(I) \cdot \sum_I H_2(I) }}} - - - - -The function returns -:math:`d(H_1, H_2)` -. - -Note: the method -``CV_COMP_BHATTACHARYYA`` -only works with normalized histograms. - -To compare a sparse histogram or more general sparse configurations of weighted points, consider using the -:ref:`CalcEMD2` -function. - - -.. index:: CreateHist - -.. _CreateHist: - -CreateHist ----------- - - - - -.. function:: CreateHist(dims, type, ranges, uniform = 1) -> hist - - Creates a histogram. - - - - - - - :param dims: for an N-dimensional histogram, list of length N giving the size of each dimension - - :type dims: sequence of int - - - :param type: Histogram representation format: ``CV_HIST_ARRAY`` means that the histogram data is represented as a multi-dimensional dense array CvMatND; ``CV_HIST_SPARSE`` means that histogram data is represented as a multi-dimensional sparse array CvSparseMat - - :type type: int - - - :param ranges: Array of ranges for the histogram bins. Its meaning depends on the ``uniform`` parameter value. The ranges are used for when the histogram is calculated or backprojected to determine which histogram bin corresponds to which value/tuple of values from the input image(s) - - :type ranges: list of tuples of ints - - - :param uniform: Uniformity flag; if not 0, the histogram has evenly - spaced bins and for every :math:`0<=i (min_value,max_value,min_idx,max_idx) - - Finds the minimum and maximum histogram bins. - - - - - - - :param hist: Histogram - - :type hist: :class:`CvHistogram` - - - :param min_value: Minimum value of the histogram - - :type min_value: :class:`CvScalar` - - - :param max_value: Maximum value of the histogram - - :type max_value: :class:`CvScalar` - - - :param min_idx: Coordinates of the minimum - - :type min_idx: sequence of int - - - :param max_idx: Coordinates of the maximum - - :type max_idx: sequence of int - - - -The function finds the minimum and -maximum histogram bins and their positions. All of output arguments are -optional. Among several extremas with the same value the ones with the -minimum index (in lexicographical order) are returned. In the case of several maximums -or minimums, the earliest in lexicographical order (extrema locations) -is returned. - - -.. index:: NormalizeHist - -.. _NormalizeHist: - -NormalizeHist -------------- - - - - -.. function:: NormalizeHist(hist,factor)-> None - - Normalizes the histogram. - - - - - - - :param hist: Pointer to the histogram - - :type hist: :class:`CvHistogram` - - - :param factor: Normalization factor - - :type factor: float - - - -The function normalizes the histogram bins by scaling them, such that the sum of the bins becomes equal to -``factor`` -. - - -.. index:: QueryHistValue_1D - -.. _QueryHistValue_1D: - -QueryHistValue_1D ------------------ - - - - -.. function:: QueryHistValue_1D(hist, idx0) -> float - - Returns the value from a 1D histogram bin. - - - - - - - :param hist: Histogram - - :type hist: :class:`CvHistogram` - - - :param idx0: bin index 0 - - :type idx0: int - - - - -.. index:: QueryHistValue_2D - -.. _QueryHistValue_2D: - -QueryHistValue_2D ------------------ - - - - -.. function:: QueryHistValue_2D(hist, idx0, idx1) -> float - - Returns the value from a 2D histogram bin. - - - - - - - :param hist: Histogram - - :type hist: :class:`CvHistogram` - - - :param idx0: bin index 0 - - :type idx0: int - - - :param idx1: bin index 1 - - :type idx1: int - - - - -.. index:: QueryHistValue_3D - -.. _QueryHistValue_3D: - -QueryHistValue_3D ------------------ - - - - -.. function:: QueryHistValue_3D(hist, idx0, idx1, idx2) -> float - - Returns the value from a 3D histogram bin. - - - - - - - :param hist: Histogram - - :type hist: :class:`CvHistogram` - - - :param idx0: bin index 0 - - :type idx0: int - - - :param idx1: bin index 1 - - :type idx1: int - - - :param idx2: bin index 2 - - :type idx2: int - - - - -.. index:: QueryHistValue_nD - -.. _QueryHistValue_nD: - -QueryHistValue_nD ------------------ - - - - -.. function:: QueryHistValue_nD(hist, idx) -> float - - Returns the value from a 1D histogram bin. - - - - - - - :param hist: Histogram - - :type hist: :class:`CvHistogram` - - - :param idx: list of indices, of same length as the dimension of the histogram's bin. - - :type idx: sequence of int - - - - -.. index:: ThreshHist - -.. _ThreshHist: - -ThreshHist ----------- - - - - -.. function:: ThreshHist(hist,threshold)-> None - - Thresholds the histogram. - - - - - - - :param hist: Pointer to the histogram - - :type hist: :class:`CvHistogram` - - - :param threshold: Threshold level - - :type threshold: float - - - -The function clears histogram bins that are below the specified threshold. - diff --git a/doc/opencv1/py/imgproc_image_filtering.rst b/doc/opencv1/py/imgproc_image_filtering.rst deleted file mode 100644 index accd698a26..0000000000 --- a/doc/opencv1/py/imgproc_image_filtering.rst +++ /dev/null @@ -1,732 +0,0 @@ -Image Filtering -=============== - -.. highlight:: python - - -Functions and classes described in this section are used to perform various linear or non-linear filtering operations on 2D images (represented as -:cpp:func:`Mat` -'s), that is, for each pixel location -:math:`(x,y)` -in the source image some its (normally rectangular) neighborhood is considered and used to compute the response. In case of a linear filter it is a weighted sum of pixel values, in case of morphological operations it is the minimum or maximum etc. The computed response is stored to the destination image at the same location -:math:`(x,y)` -. It means, that the output image will be of the same size as the input image. Normally, the functions supports multi-channel arrays, in which case every channel is processed independently, therefore the output image will also have the same number of channels as the input one. - -Another common feature of the functions and classes described in this section is that, unlike simple arithmetic functions, they need to extrapolate values of some non-existing pixels. For example, if we want to smooth an image using a Gaussian -:math:`3 \times 3` -filter, then during the processing of the left-most pixels in each row we need pixels to the left of them, i.e. outside of the image. We can let those pixels be the same as the left-most image pixels (i.e. use "replicated border" extrapolation method), or assume that all the non-existing pixels are zeros ("contant border" extrapolation method) etc. - -.. index:: IplConvKernel - -.. _IplConvKernel: - -IplConvKernel -------------- - - - -.. class:: IplConvKernel - - - -An IplConvKernel is a rectangular convolution kernel, created by function -:ref:`CreateStructuringElementEx` -. - - -.. index:: CopyMakeBorder - -.. _CopyMakeBorder: - -CopyMakeBorder --------------- - - - - -.. function:: CopyMakeBorder(src,dst,offset,bordertype,value=(0,0,0,0))-> None - - Copies an image and makes a border around it. - - - - - - - :param src: The source image - - :type src: :class:`CvArr` - - - :param dst: The destination image - - :type dst: :class:`CvArr` - - - :param offset: Coordinates of the top-left corner (or bottom-left in the case of images with bottom-left origin) of the destination image rectangle where the source image (or its ROI) is copied. Size of the rectanlge matches the source image size/ROI size - - :type offset: :class:`CvPoint` - - - :param bordertype: Type of the border to create around the copied source image rectangle; types include: - - * **IPL_BORDER_CONSTANT** border is filled with the fixed value, passed as last parameter of the function. - - * **IPL_BORDER_REPLICATE** the pixels from the top and bottom rows, the left-most and right-most columns are replicated to fill the border. - - - (The other two border types from IPL, ``IPL_BORDER_REFLECT`` and ``IPL_BORDER_WRAP`` , are currently unsupported) - - :type bordertype: int - - - :param value: Value of the border pixels if ``bordertype`` is ``IPL_BORDER_CONSTANT`` - - :type value: :class:`CvScalar` - - - -The function copies the source 2D array into the interior of the destination array and makes a border of the specified type around the copied area. The function is useful when one needs to emulate border type that is different from the one embedded into a specific algorithm implementation. For example, morphological functions, as well as most of other filtering functions in OpenCV, internally use replication border type, while the user may need a zero border or a border, filled with 1's or 255's. - - -.. index:: CreateStructuringElementEx - -.. _CreateStructuringElementEx: - -CreateStructuringElementEx --------------------------- - - - - -.. function:: CreateStructuringElementEx(cols,rows,anchorX,anchorY,shape,values=None)-> kernel - - Creates a structuring element. - - - - - - - :param cols: Number of columns in the structuring element - - :type cols: int - - - :param rows: Number of rows in the structuring element - - :type rows: int - - - :param anchorX: Relative horizontal offset of the anchor point - - :type anchorX: int - - - :param anchorY: Relative vertical offset of the anchor point - - :type anchorY: int - - - :param shape: Shape of the structuring element; may have the following values: - - - * **CV_SHAPE_RECT** a rectangular element - - - * **CV_SHAPE_CROSS** a cross-shaped element - - - * **CV_SHAPE_ELLIPSE** an elliptic element - - - * **CV_SHAPE_CUSTOM** a user-defined element. In this case the parameter ``values`` specifies the mask, that is, which neighbors of the pixel must be considered - - - - :type shape: int - - - :param values: Pointer to the structuring element data, a plane array, representing row-by-row scanning of the element matrix. Non-zero values indicate points that belong to the element. If the pointer is ``NULL`` , then all values are considered non-zero, that is, the element is of a rectangular shape. This parameter is considered only if the shape is ``CV_SHAPE_CUSTOM`` - - :type values: sequence of int - - - -The function CreateStructuringElementEx allocates and fills the structure -``IplConvKernel`` -, which can be used as a structuring element in the morphological operations. - - -.. index:: Dilate - -.. _Dilate: - -Dilate ------- - - - - -.. function:: Dilate(src,dst,element=None,iterations=1)-> None - - Dilates an image by using a specific structuring element. - - - :param src: Source image - - :type src: :class:`CvArr` - - :param dst: Destination image - - :type dst: :class:`CvArr` - - :param element: Structuring element used for dilation. If it is ``None`` , a ``3 x 3`` rectangular structuring element is used - - :type element: :class:`IplConvKernel` - - :param iterations: Number of times dilation is applied - - :type iterations: int - - -The function dilates the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the maximum is taken: - - - -.. math:: - - \max _{(x',y') \, in \, \texttt{element} }src(x+x',y+y') - - -The function supports the in-place mode. Dilation can be applied several (``iterations``) times. For color images, each channel is processed independently. - - -.. index:: Erode - -.. _Erode: - -Erode ------ - - - - -.. function:: Erode(src,dst,element=None,iterations=1)-> None - - Erodes an image by using a specific structuring element. - - - :param src: Source image - - :type src: :class:`CvArr` - - :param dst: Destination image - - :type dst: :class:`CvArr` - - :param element: Structuring element used for erosion. If it is ``None`` , a ``3 x 3`` rectangular structuring element is used - - :type element: :class:`IplConvKernel` - - - :param iterations: Number of times erosion is applied - - :type iterations: int - - - -The function erodes the source image using the specified structuring element that determines the shape of a pixel neighborhood over which the minimum is taken: - - - -.. math:: - - \min _{(x',y') \, in \, \texttt{element} }src(x+x',y+y') - - -The function supports the in-place mode. Erosion can be applied several ( -``iterations`` -) times. For color images, each channel is processed independently. - - -.. index:: Filter2D - -.. _Filter2D: - -Filter2D --------- - - - - -.. function:: Filter2D(src,dst,kernel,anchor=(-1,-1))-> None - - Convolves an image with the kernel. - - - - - - - :param src: The source image - - :type src: :class:`CvArr` - - - :param dst: The destination image - - :type dst: :class:`CvArr` - - - :param kernel: Convolution kernel, a single-channel floating point matrix. If you want to apply different kernels to different channels, split the image into separate color planes using :ref:`Split` and process them individually - - :type kernel: :class:`CvMat` - - - :param anchor: The anchor of the kernel that indicates the relative position of a filtered point within the kernel. The anchor shoud lie within the kernel. The special default value (-1,-1) means that it is at the kernel center - - :type anchor: :class:`CvPoint` - - - -The function applies an arbitrary linear filter to the image. In-place operation is supported. When the aperture is partially outside the image, the function interpolates outlier pixel values from the nearest pixels that are inside the image. - - -.. index:: Laplace - -.. _Laplace: - -Laplace -------- - - - - -.. function:: Laplace(src,dst,apertureSize=3)-> None - - Calculates the Laplacian of an image. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param apertureSize: Aperture size (it has the same meaning as :ref:`Sobel` ) - - :type apertureSize: int - - - -The function calculates the Laplacian of the source image by adding up the second x and y derivatives calculated using the Sobel operator: - - - -.. math:: - - \texttt{dst} (x,y) = \frac{d^2 \texttt{src}}{dx^2} + \frac{d^2 \texttt{src}}{dy^2} - - -Setting -``apertureSize`` -= 1 gives the fastest variant that is equal to convolving the image with the following kernel: - - - -.. math:: - - \vecthreethree {0}{1}{0}{1}{-4}{1}{0}{1}{0} - - -Similar to the -:ref:`Sobel` -function, no scaling is done and the same combinations of input and output formats are supported. - - -.. index:: MorphologyEx - -.. _MorphologyEx: - -MorphologyEx ------------- - - - - -.. function:: MorphologyEx(src,dst,temp,element,operation,iterations=1)-> None - - Performs advanced morphological transformations. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param temp: Temporary image, required in some cases - - :type temp: :class:`CvArr` - - - :param element: Structuring element - - :type element: :class:`IplConvKernel` - - - :param operation: Type of morphological operation, one of the following: - - * **CV_MOP_OPEN** opening - - * **CV_MOP_CLOSE** closing - - * **CV_MOP_GRADIENT** morphological gradient - - * **CV_MOP_TOPHAT** "top hat" - - * **CV_MOP_BLACKHAT** "black hat" - - - - :type operation: int - - - :param iterations: Number of times erosion and dilation are applied - - :type iterations: int - - - -The function can perform advanced morphological transformations using erosion and dilation as basic operations. - -Opening: - - - -.. math:: - - dst=open(src,element)=dilate(erode(src,element),element) - - -Closing: - - - -.. math:: - - dst=close(src,element)=erode(dilate(src,element),element) - - -Morphological gradient: - - - -.. math:: - - dst=morph \_ grad(src,element)=dilate(src,element)-erode(src,element) - - -"Top hat": - - - -.. math:: - - dst=tophat(src,element)=src-open(src,element) - - -"Black hat": - - - -.. math:: - - dst=blackhat(src,element)=close(src,element)-src - - -The temporary image -``temp`` -is required for a morphological gradient and, in the case of in-place operation, for "top hat" and "black hat". - - -.. index:: PyrDown - -.. _PyrDown: - -PyrDown -------- - - - - -.. function:: PyrDown(src,dst,filter=CV_GAUSSIAN_5X5)-> None - - Downsamples an image. - - - - - - - :param src: The source image - - :type src: :class:`CvArr` - - - :param dst: The destination image, should have a half as large width and height than the source - - :type dst: :class:`CvArr` - - - :param filter: Type of the filter used for convolution; only ``CV_GAUSSIAN_5x5`` is currently supported - - :type filter: int - - - -The function performs the downsampling step of the Gaussian pyramid decomposition. First it convolves the source image with the specified filter and then downsamples the image by rejecting even rows and columns. - - -.. index:: Smooth - -.. _Smooth: - -Smooth ------- - - - - -.. function:: Smooth(src,dst,smoothtype=CV_GAUSSIAN,param1=3,param2=0,param3=0,param4=0)-> None - - Smooths the image in one of several ways. - - - - - - - :param src: The source image - - :type src: :class:`CvArr` - - - :param dst: The destination image - - :type dst: :class:`CvArr` - - - :param smoothtype: Type of the smoothing: - - - * **CV_BLUR_NO_SCALE** linear convolution with :math:`\texttt{param1}\times\texttt{param2}` box kernel (all 1's). If you want to smooth different pixels with different-size box kernels, you can use the integral image that is computed using :ref:`Integral` - - - * **CV_BLUR** linear convolution with :math:`\texttt{param1}\times\texttt{param2}` box kernel (all 1's) with subsequent scaling by :math:`1/(\texttt{param1}\cdot\texttt{param2})` - - - * **CV_GAUSSIAN** linear convolution with a :math:`\texttt{param1}\times\texttt{param2}` Gaussian kernel - - - * **CV_MEDIAN** median filter with a :math:`\texttt{param1}\times\texttt{param1}` square aperture - - - * **CV_BILATERAL** bilateral filter with a :math:`\texttt{param1}\times\texttt{param1}` square aperture, color sigma= ``param3`` and spatial sigma= ``param4`` . If ``param1=0`` , the aperture square side is set to ``cvRound(param4*1.5)*2+1`` . Information about bilateral filtering can be found at http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/MANDUCHI1/Bilateral\_Filtering.html - - - - :type smoothtype: int - - - :param param1: The first parameter of the smoothing operation, the aperture width. Must be a positive odd number (1, 3, 5, ...) - - :type param1: int - - - :param param2: The second parameter of the smoothing operation, the aperture height. Ignored by ``CV_MEDIAN`` and ``CV_BILATERAL`` methods. In the case of simple scaled/non-scaled and Gaussian blur if ``param2`` is zero, it is set to ``param1`` . Otherwise it must be a positive odd number. - - :type param2: int - - - :param param3: In the case of a Gaussian parameter this parameter may specify Gaussian :math:`\sigma` (standard deviation). If it is zero, it is calculated from the kernel size: - - .. math:: - - \sigma = 0.3 (n/2 - 1) + 0.8 \quad \text{where} \quad n= \begin{array}{l l} \mbox{\texttt{param1} for horizontal kernel} \\ \mbox{\texttt{param2} for vertical kernel} \end{array} - - Using standard sigma for small kernels ( :math:`3\times 3` to :math:`7\times 7` ) gives better speed. If ``param3`` is not zero, while ``param1`` and ``param2`` are zeros, the kernel size is calculated from the sigma (to provide accurate enough operation). - - :type param3: float - - - -The function smooths an image using one of several methods. Every of the methods has some features and restrictions listed below - -Blur with no scaling works with single-channel images only and supports accumulation of 8-bit to 16-bit format (similar to -:ref:`Sobel` -and -:ref:`Laplace` -) and 32-bit floating point to 32-bit floating-point format. - -Simple blur and Gaussian blur support 1- or 3-channel, 8-bit and 32-bit floating point images. These two methods can process images in-place. - -Median and bilateral filters work with 1- or 3-channel 8-bit images and can not process images in-place. - - -.. index:: Sobel - -.. _Sobel: - -Sobel ------ - - - - -.. function:: Sobel(src,dst,xorder,yorder,apertureSize = 3)-> None - - Calculates the first, second, third or mixed image derivatives using an extended Sobel operator. - - - - - - - :param src: Source image of type CvArr* - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param xorder: Order of the derivative x - - :type xorder: int - - - :param yorder: Order of the derivative y - - :type yorder: int - - - :param apertureSize: Size of the extended Sobel kernel, must be 1, 3, 5 or 7 - - :type apertureSize: int - - - -In all cases except 1, an -:math:`\texttt{apertureSize} \times -\texttt{apertureSize}` -separable kernel will be used to calculate the -derivative. For -:math:`\texttt{apertureSize} = 1` -a -:math:`3 \times 1` -or -:math:`1 \times 3` -a kernel is used (Gaussian smoothing is not done). There is also the special -value -``CV_SCHARR`` -(-1) that corresponds to a -:math:`3\times3` -Scharr -filter that may give more accurate results than a -:math:`3\times3` -Sobel. Scharr -aperture is - - - -.. math:: - - \vecthreethree{-3}{0}{3}{-10}{0}{10}{-3}{0}{3} - - -for the x-derivative or transposed for the y-derivative. - -The function calculates the image derivative by convolving the image with the appropriate kernel: - - - -.. math:: - - \texttt{dst} (x,y) = \frac{d^{xorder+yorder} \texttt{src}}{dx^{xorder} \cdot dy^{yorder}} - - -The Sobel operators combine Gaussian smoothing and differentiation -so the result is more or less resistant to the noise. Most often, -the function is called with ( -``xorder`` -= 1, -``yorder`` -= 0, -``apertureSize`` -= 3) or ( -``xorder`` -= 0, -``yorder`` -= 1, -``apertureSize`` -= 3) to calculate the first x- or y- image -derivative. The first case corresponds to a kernel of: - - - -.. math:: - - \vecthreethree{-1}{0}{1}{-2}{0}{2}{-1}{0}{1} - - -and the second one corresponds to a kernel of: - - -.. math:: - - \vecthreethree{-1}{-2}{-1}{0}{0}{0}{1}{2}{1} - - -or a kernel of: - - -.. math:: - - \vecthreethree{1}{2}{1}{0}{0}{0}{-1}{2}{-1} - - -depending on the image origin ( -``origin`` -field of -``IplImage`` -structure). No scaling is done, so the destination image -usually has larger numbers (in absolute values) than the source image does. To -avoid overflow, the function requires a 16-bit destination image if the -source image is 8-bit. The result can be converted back to 8-bit using the -:ref:`ConvertScale` -or the -:ref:`ConvertScaleAbs` -function. Besides 8-bit images -the function can process 32-bit floating-point images. Both the source and the -destination must be single-channel images of equal size or equal ROI size. - diff --git a/doc/opencv1/py/imgproc_miscellaneous_image_transformations.rst b/doc/opencv1/py/imgproc_miscellaneous_image_transformations.rst deleted file mode 100644 index 0c1ea1d40e..0000000000 --- a/doc/opencv1/py/imgproc_miscellaneous_image_transformations.rst +++ /dev/null @@ -1,1473 +0,0 @@ -Miscellaneous Image Transformations -=================================== - -.. highlight:: python - - - -.. index:: AdaptiveThreshold - -.. _AdaptiveThreshold: - -AdaptiveThreshold ------------------ - - - - -.. function:: AdaptiveThreshold(src,dst,maxValue, adaptive_method=CV_ADAPTIVE_THRESH_MEAN_C, thresholdType=CV_THRESH_BINARY,blockSize=3,param1=5)-> None - - Applies an adaptive threshold to an array. - - - - - - - :param src: Source image - - :type src: :class:`CvArr` - - - :param dst: Destination image - - :type dst: :class:`CvArr` - - - :param maxValue: Maximum value that is used with ``CV_THRESH_BINARY`` and ``CV_THRESH_BINARY_INV`` - - :type maxValue: float - - - :param adaptive_method: Adaptive thresholding algorithm to use: ``CV_ADAPTIVE_THRESH_MEAN_C`` or ``CV_ADAPTIVE_THRESH_GAUSSIAN_C`` (see the discussion) - - :type adaptive_method: int - - - :param thresholdType: Thresholding type; must be one of - - * **CV_THRESH_BINARY** xxx - - * **CV_THRESH_BINARY_INV** xxx - - - - :type thresholdType: int - - - :param blockSize: The size of a pixel neighborhood that is used to calculate a threshold value for the pixel: 3, 5, 7, and so on - - :type blockSize: int - - - :param param1: The method-dependent parameter. For the methods ``CV_ADAPTIVE_THRESH_MEAN_C`` and ``CV_ADAPTIVE_THRESH_GAUSSIAN_C`` it is a constant subtracted from the mean or weighted mean (see the discussion), though it may be negative - - :type param1: float - - - -The function transforms a grayscale image to a binary image according to the formulas: - - - - - * **CV_THRESH_BINARY** - - .. math:: - - dst(x,y) = \fork{\texttt{maxValue}}{if $src(x,y) > T(x,y)$}{0}{otherwise} - - - - - * **CV_THRESH_BINARY_INV** - - .. math:: - - dst(x,y) = \fork{0}{if $src(x,y) > T(x,y)$}{\texttt{maxValue}}{otherwise} - - - - - -where -:math:`T(x,y)` -is a threshold calculated individually for each pixel. - -For the method -``CV_ADAPTIVE_THRESH_MEAN_C`` -it is the mean of a -:math:`\texttt{blockSize} \times \texttt{blockSize}` -pixel neighborhood, minus -``param1`` -. - -For the method -``CV_ADAPTIVE_THRESH_GAUSSIAN_C`` -it is the weighted sum (gaussian) of a -:math:`\texttt{blockSize} \times \texttt{blockSize}` -pixel neighborhood, minus -``param1`` -. - - -.. index:: CvtColor - -.. _CvtColor: - -CvtColor --------- - - - - -.. function:: CvtColor(src,dst,code)-> None - - Converts an image from one color space to another. - - - - - - - :param src: The source 8-bit (8u), 16-bit (16u) or single-precision floating-point (32f) image - - :type src: :class:`CvArr` - - - :param dst: The destination image of the same data type as the source. The number of channels may be different - - :type dst: :class:`CvArr` - - - :param code: Color conversion operation that can be specifed using ``CV_ *src_color_space* 2 *dst_color_space*`` constants (see below) - - :type code: int - - - -The function converts the input image from one color -space to another. The function ignores the -``colorModel`` -and -``channelSeq`` -fields of the -``IplImage`` -header, so the -source image color space should be specified correctly (including -order of the channels in the case of RGB space. For example, BGR means 24-bit -format with -:math:`B_0, G_0, R_0, B_1, G_1, R_1, ...` -layout -whereas RGB means 24-format with -:math:`R_0, G_0, B_0, R_1, G_1, B_1, ...` -layout). - -The conventional range for R,G,B channel values is: - - - - - -* - 0 to 255 for 8-bit images - - -* - 0 to 65535 for 16-bit images and - - -* - 0 to 1 for floating-point images. - - -Of course, in the case of linear transformations the range can be -specific, but in order to get correct results in the case of non-linear -transformations, the input image should be scaled. - -The function can do the following transformations: - - - - - -* - Transformations within RGB space like adding/removing the alpha channel, reversing the channel order, conversion to/from 16-bit RGB color (R5:G6:B5 or R5:G5:B5), as well as conversion to/from grayscale using: - - - .. math:: - - \text{RGB[A] to Gray:} Y \leftarrow 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B - - - and - - - .. math:: - - \text{Gray to RGB[A]:} R \leftarrow Y, G \leftarrow Y, B \leftarrow Y, A \leftarrow 0 - - - The conversion from a RGB image to gray is done with: - - - - :: - - - - cvCvtColor(src ,bwsrc, CV_RGB2GRAY) - - - .. - - - -* - RGB - :math:`\leftrightarrow` - CIE XYZ.Rec 709 with D65 white point ( - ``CV_BGR2XYZ, CV_RGB2XYZ, CV_XYZ2BGR, CV_XYZ2RGB`` - ): - - - .. math:: - - \begin{bmatrix} X \\ Y \\ Z \end{bmatrix} \leftarrow \begin{bmatrix} 0.412453 & 0.357580 & 0.180423 \\ 0.212671 & 0.715160 & 0.072169 \\ 0.019334 & 0.119193 & 0.950227 \end{bmatrix} \cdot \begin{bmatrix} R \\ G \\ B \end{bmatrix} - - - - - .. math:: - - \begin{bmatrix} R \\ G \\ B \end{bmatrix} \leftarrow \begin{bmatrix} 3.240479 & -1.53715 & -0.498535 \\ -0.969256 & 1.875991 & 0.041556 \\ 0.055648 & -0.204043 & 1.057311 \end{bmatrix} \cdot \begin{bmatrix} X \\ Y \\ Z \end{bmatrix} - - - :math:`X` - , - :math:`Y` - and - :math:`Z` - cover the whole value range (in the case of floating-point images - :math:`Z` - may exceed 1). - - - -* - RGB - :math:`\leftrightarrow` - YCrCb JPEG (a.k.a. YCC) ( - ``CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB`` - ) - - - .. math:: - - Y \leftarrow 0.299 \cdot R + 0.587 \cdot G + 0.114 \cdot B - - - - - .. math:: - - Cr \leftarrow (R-Y) \cdot 0.713 + delta - - - - - .. math:: - - Cb \leftarrow (B-Y) \cdot 0.564 + delta - - - - - .. math:: - - R \leftarrow Y + 1.403 \cdot (Cr - delta) - - - - - .. math:: - - G \leftarrow Y - 0.344 \cdot (Cr - delta) - 0.714 \cdot (Cb - delta) - - - - - .. math:: - - B \leftarrow Y + 1.773 \cdot (Cb - delta) - - - where - - - .. math:: - - delta = \left \{ \begin{array}{l l} 128 & \mbox{for 8-bit images} \\ 32768 & \mbox{for 16-bit images} \\ 0.5 & \mbox{for floating-point images} \end{array} \right . - - - Y, Cr and Cb cover the whole value range. - - - -* - RGB - :math:`\leftrightarrow` - HSV ( - ``CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB`` - ) - in the case of 8-bit and 16-bit images - R, G and B are converted to floating-point format and scaled to fit the 0 to 1 range - - - .. math:: - - V \leftarrow max(R,G,B) - - - - - .. math:: - - S \leftarrow \fork{\frac{V-min(R,G,B)}{V}}{if $V \neq 0$}{0}{otherwise} - - - - - .. math:: - - H \leftarrow \forkthree{{60(G - B)}/{S}}{if $V=R$}{{120+60(B - R)}/{S}}{if $V=G$}{{240+60(R - G)}/{S}}{if $V=B$} - - - if - :math:`H<0` - then - :math:`H \leftarrow H+360` - On output - :math:`0 \leq V \leq 1` - , - :math:`0 \leq S \leq 1` - , - :math:`0 \leq H \leq 360` - . - - The values are then converted to the destination data type: - - - - - * 8-bit images - - - .. math:: - - V \leftarrow 255 V, S \leftarrow 255 S, H \leftarrow H/2 \text{(to fit to 0 to 255)} - - - - - * 16-bit images (currently not supported) - - - .. math:: - - V <- 65535 V, S <- 65535 S, H <- H - - - - - * 32-bit images - H, S, V are left as is - - - - -* - RGB - :math:`\leftrightarrow` - HLS ( - ``CV_BGR2HLS, CV_RGB2HLS, CV_HLS2BGR, CV_HLS2RGB`` - ). - in the case of 8-bit and 16-bit images - R, G and B are converted to floating-point format and scaled to fit the 0 to 1 range. - - - .. math:: - - V_{max} \leftarrow {max}(R,G,B) - - - - - .. math:: - - V_{min} \leftarrow {min}(R,G,B) - - - - - .. math:: - - L \leftarrow \frac{V_{max} + V_{min}}{2} - - - - - .. math:: - - S \leftarrow \fork{\frac{V_{max} - V_{min}}{V_{max} + V_{min}}}{if $L < 0.5$}{\frac{V_{max} - V_{min}}{2 - (V_{max} + V_{min})}}{if $L \ge 0.5$} - - - - - .. math:: - - H \leftarrow \forkthree{{60(G - B)}/{S}}{if $V_{max}=R$}{{120+60(B - R)}/{S}}{if $V_{max}=G$}{{240+60(R - G)}/{S}}{if $V_{max}=B$} - - - if - :math:`H<0` - then - :math:`H \leftarrow H+360` - On output - :math:`0 \leq L \leq 1` - , - :math:`0 \leq S \leq 1` - , - :math:`0 \leq H \leq 360` - . - - The values are then converted to the destination data type: - - - - - * 8-bit images - - - .. math:: - - V \leftarrow 255 V, S \leftarrow 255 S, H \leftarrow H/2 \text{(to fit to 0 to 255)} - - - - - * 16-bit images (currently not supported) - - - .. math:: - - V <- 65535 V, S <- 65535 S, H <- H - - - - - * 32-bit images - H, S, V are left as is - - - - -* - RGB - :math:`\leftrightarrow` - CIE L*a*b* ( - ``CV_BGR2Lab, CV_RGB2Lab, CV_Lab2BGR, CV_Lab2RGB`` - ) - in the case of 8-bit and 16-bit images - R, G and B are converted to floating-point format and scaled to fit the 0 to 1 range - - - .. math:: - - \vecthree{X}{Y}{Z} \leftarrow \vecthreethree{0.412453}{0.357580}{0.180423}{0.212671}{0.715160}{0.072169}{0.019334}{0.119193}{0.950227} \cdot \vecthree{R}{G}{B} - - - - - .. math:: - - X \leftarrow X/X_n, \text{where} X_n = 0.950456 - - - - - .. math:: - - Z \leftarrow Z/Z_n, \text{where} Z_n = 1.088754 - - - - - .. math:: - - L \leftarrow \fork{116*Y^{1/3}-16}{for $Y>0.008856$}{903.3*Y}{for $Y \le 0.008856$} - - - - - .. math:: - - a \leftarrow 500 (f(X)-f(Y)) + delta - - - - - .. math:: - - b \leftarrow 200 (f(Y)-f(Z)) + delta - - - where - - - .. math:: - - f(t)= \fork{t^{1/3}}{for $t>0.008856$}{7.787 t+16/116}{for $t<=0.008856$} - - - and - - - .. math:: - - delta = \fork{128}{for 8-bit images}{0}{for floating-point images} - - - On output - :math:`0 \leq L \leq 100` - , - :math:`-127 \leq a \leq 127` - , - :math:`-127 \leq b \leq 127` - The values are then converted to the destination data type: - - - - - * 8-bit images - - - .. math:: - - L \leftarrow L*255/100, a \leftarrow a + 128, b \leftarrow b + 128 - - - - - * 16-bit images - currently not supported - - - * 32-bit images - L, a, b are left as is - - - - -* - RGB - :math:`\leftrightarrow` - CIE L*u*v* ( - ``CV_BGR2Luv, CV_RGB2Luv, CV_Luv2BGR, CV_Luv2RGB`` - ) - in the case of 8-bit and 16-bit images - R, G and B are converted to floating-point format and scaled to fit 0 to 1 range - - - .. math:: - - \vecthree{X}{Y}{Z} \leftarrow \vecthreethree{0.412453}{0.357580}{0.180423}{0.212671}{0.715160}{0.072169}{0.019334}{0.119193}{0.950227} \cdot \vecthree{R}{G}{B} - - - - - .. math:: - - L \leftarrow \fork{116 Y^{1/3}}{for $Y>0.008856$}{903.3 Y}{for $Y<=0.008856$} - - - - - .. math:: - - u' \leftarrow 4*X/(X + 15*Y + 3 Z) - - - - - .. math:: - - v' \leftarrow 9*Y/(X + 15*Y + 3 Z) - - - - - .. math:: - - u \leftarrow 13*L*(u' - u_n) \quad \text{where} \quad u_n=0.19793943 - - - - - .. math:: - - v \leftarrow 13*L*(v' - v_n) \quad \text{where} \quad v_n=0.46831096 - - - On output - :math:`0 \leq L \leq 100` - , - :math:`-134 \leq u \leq 220` - , - :math:`-140 \leq v \leq 122` - . - - The values are then converted to the destination data type: - - - - - * 8-bit images - - - .. math:: - - L \leftarrow 255/100 L, u \leftarrow 255/354 (u + 134), v \leftarrow 255/256 (v + 140) - - - - - * 16-bit images - currently not supported - - - * 32-bit images - L, u, v are left as is - - - The above formulas for converting RGB to/from various color spaces have been taken from multiple sources on Web, primarily from - the Ford98 - at the Charles Poynton site. - - - -* - Bayer - :math:`\rightarrow` - RGB ( - ``CV_BayerBG2BGR, CV_BayerGB2BGR, CV_BayerRG2BGR, CV_BayerGR2BGR, CV_BayerBG2RGB, CV_BayerGB2RGB, CV_BayerRG2RGB, CV_BayerGR2RGB`` - ) The Bayer pattern is widely used in CCD and CMOS cameras. It allows one to get color pictures from a single plane where R,G and B pixels (sensors of a particular component) are interleaved like this: - - .. image:: ../pics/bayer.png - - The output RGB components of a pixel are interpolated from 1, 2 or - 4 neighbors of the pixel having the same color. There are several - modifications of the above pattern that can be achieved by shifting - the pattern one pixel left and/or one pixel up. The two letters - :math:`C_1` - and - :math:`C_2` - in the conversion constants - ``CV_Bayer`` - :math:`C_1 C_2` - ``2BGR`` - and - ``CV_Bayer`` - :math:`C_1 C_2` - ``2RGB`` - indicate the particular pattern - type - these are components from the second row, second and third - columns, respectively. For example, the above pattern has very - popular "BG" type. - - - -.. index:: DistTransform - -.. _DistTransform: - -DistTransform -------------- - - - - -.. function:: DistTransform(src,dst,distance_type=CV_DIST_L2,mask_size=3,mask=None,labels=NULL)-> None - - Calculates the distance to the closest zero pixel for all non-zero pixels of the source image. - - - - - - - :param src: 8-bit, single-channel (binary) source image - - :type src: :class:`CvArr` - - - :param dst: Output image with calculated distances (32-bit floating-point, single-channel) - - :type dst: :class:`CvArr` - - - :param distance_type: Type of distance; can be ``CV_DIST_L1, CV_DIST_L2, CV_DIST_C`` or ``CV_DIST_USER`` - - :type distance_type: int - - - :param mask_size: Size of the distance transform mask; can be 3 or 5. in the case of ``CV_DIST_L1`` or ``CV_DIST_C`` the parameter is forced to 3, because a :math:`3\times 3` mask gives the same result as a :math:`5\times 5` yet it is faster - - :type mask_size: int - - - :param mask: User-defined mask in the case of a user-defined distance, it consists of 2 numbers (horizontal/vertical shift cost, diagonal shift cost) in the case ofa :math:`3\times 3` mask and 3 numbers (horizontal/vertical shift cost, diagonal shift cost, knight's move cost) in the case of a :math:`5\times 5` mask - - :type mask: sequence of float - - - :param labels: The optional output 2d array of integer type labels, the same size as ``src`` and ``dst`` - - :type labels: :class:`CvArr` - - - -The function calculates the approximated -distance from every binary image pixel to the nearest zero pixel. -For zero pixels the function sets the zero distance, for others it -finds the shortest path consisting of basic shifts: horizontal, -vertical, diagonal or knight's move (the latest is available for a -:math:`5\times 5` -mask). The overall distance is calculated as a sum of these -basic distances. Because the distance function should be symmetric, -all of the horizontal and vertical shifts must have the same cost (that -is denoted as -``a`` -), all the diagonal shifts must have the -same cost (denoted -``b`` -), and all knight's moves must have -the same cost (denoted -``c`` -). For -``CV_DIST_C`` -and -``CV_DIST_L1`` -types the distance is calculated precisely, -whereas for -``CV_DIST_L2`` -(Euclidian distance) the distance -can be calculated only with some relative error (a -:math:`5\times 5` -mask -gives more accurate results), OpenCV uses the values suggested in -Borgefors86 -: - - - -.. table:: - - ============== =================== ====================== - ``CV_DIST_C`` :math:`(3\times 3)` a = 1, b = 1 \ - ============== =================== ====================== - ``CV_DIST_L1`` :math:`(3\times 3)` a = 1, b = 2 \ - ``CV_DIST_L2`` :math:`(3\times 3)` a=0.955, b=1.3693 \ - ``CV_DIST_L2`` :math:`(5\times 5)` a=1, b=1.4, c=2.1969 \ - ============== =================== ====================== - -And below are samples of the distance field (black (0) pixel is in the middle of white square) in the case of a user-defined distance: - -User-defined -:math:`3 \times 3` -mask (a=1, b=1.5) - - -.. table:: - - === === === = === === ===== - 4.5 4 3.5 3 3.5 4 4.5 \ - === === === = === === ===== - 4 3 2.5 2 2.5 3 4 \ - 3.5 2.5 1.5 1 1.5 2.5 3.5 \ - 3 2 1 1 2 3 \ - 3.5 2.5 1.5 1 1.5 2.5 3.5 \ - 4 3 2.5 2 2.5 3 4 \ - 4.5 4 3.5 3 3.5 4 4.5 \ - === === === = === === ===== - -User-defined -:math:`5 \times 5` -mask (a=1, b=1.5, c=2) - - -.. table:: - - === === === = === === ===== - 4.5 3.5 3 3 3 3.5 4.5 \ - === === === = === === ===== - 3.5 3 2 2 2 3 3.5 \ - 3 2 1.5 1 1.5 2 3 \ - 3 2 1 1 2 3 \ - 3 2 1.5 1 1.5 2 3 \ - 3.5 3 2 2 2 3 3.5 \ - 4 3.5 3 3 3 3.5 4 \ - === === === = === === ===== - -Typically, for a fast, coarse distance estimation -``CV_DIST_L2`` -, -a -:math:`3\times 3` -mask is used, and for a more accurate distance estimation -``CV_DIST_L2`` -, a -:math:`5\times 5` -mask is used. - -When the output parameter -``labels`` -is not -``NULL`` -, for -every non-zero pixel the function also finds the nearest connected -component consisting of zero pixels. The connected components -themselves are found as contours in the beginning of the function. - -In this mode the processing time is still O(N), where N is the number of -pixels. Thus, the function provides a very fast way to compute approximate -Voronoi diagram for the binary image. - - -.. index:: CvConnectedComp - -.. _CvConnectedComp: - -CvConnectedComp ---------------- - - - -.. class:: CvConnectedComp - - - -Connected component, represented as a tuple (area, value, rect), where -area is the area of the component as a float, value is the average color -as a -:ref:`CvScalar` -, and rect is the ROI of the component, as a -:ref:`CvRect` -. - -.. index:: FloodFill - -.. _FloodFill: - -FloodFill ---------- - - - - -.. function:: FloodFill(image,seed_point,new_val,lo_diff=(0,0,0,0),up_diff=(0,0,0,0),flags=4,mask=NULL)-> comp - - Fills a connected component with the given color. - - - - - - - :param image: Input 1- or 3-channel, 8-bit or floating-point image. It is modified by the function unless the ``CV_FLOODFILL_MASK_ONLY`` flag is set (see below) - - :type image: :class:`CvArr` - - - :param seed_point: The starting point - - :type seed_point: :class:`CvPoint` - - - :param new_val: New value of the repainted domain pixels - - :type new_val: :class:`CvScalar` - - - :param lo_diff: Maximal lower brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component. In the case of 8-bit color images it is a packed value - - :type lo_diff: :class:`CvScalar` - - - :param up_diff: Maximal upper brightness/color difference between the currently observed pixel and one of its neighbors belonging to the component, or a seed pixel being added to the component. In the case of 8-bit color images it is a packed value - - :type up_diff: :class:`CvScalar` - - - :param comp: Returned connected component for the repainted domain. Note that the function does not fill ``comp->contour`` field. The boundary of the filled component can be retrieved from the output mask image using :ref:`FindContours` - - :type comp: :class:`CvConnectedComp` - - - :param flags: The operation flags. Lower bits contain connectivity value, 4 (by default) or 8, used within the function. Connectivity determines which neighbors of a pixel are considered. Upper bits can be 0 or a combination of the following flags: - - - * **CV_FLOODFILL_FIXED_RANGE** if set, the difference between the current pixel and seed pixel is considered, otherwise the difference between neighbor pixels is considered (the range is floating) - - - * **CV_FLOODFILL_MASK_ONLY** if set, the function does not fill the image ( ``new_val`` is ignored), but fills the mask (that must be non-NULL in this case) - - - - :type flags: int - - - :param mask: Operation mask, should be a single-channel 8-bit image, 2 pixels wider and 2 pixels taller than ``image`` . If not NULL, the function uses and updates the mask, so the user takes responsibility of initializing the ``mask`` content. Floodfilling can't go across non-zero pixels in the mask, for example, an edge detector output can be used as a mask to stop filling at edges. It is possible to use the same mask in multiple calls to the function to make sure the filled area do not overlap. **Note** : because the mask is larger than the filled image, a pixel in ``mask`` that corresponds to :math:`(x,y)` pixel in ``image`` will have coordinates :math:`(x+1,y+1)` - - :type mask: :class:`CvArr` - - - -The function fills a connected component starting from the seed point with the specified color. The connectivity is determined by the closeness of pixel values. The pixel at -:math:`(x,y)` -is considered to belong to the repainted domain if: - - - - - -* grayscale image, floating range - - - .. math:: - - src(x',y')- \texttt{lo\_diff} <= src(x,y) <= src(x',y')+ \texttt{up\_diff} - - - - -* grayscale image, fixed range - - - .. math:: - - src(seed.x,seed.y)- \texttt{lo\_diff} <=src(x,y)<=src(seed.x,seed.y)+ \texttt{up\_diff} - - - - -* color image, floating range - - - .. math:: - - src(x',y')_r- \texttt{lo\_diff} _r<=src(x,y)_r<=src(x',y')_r+ \texttt{up\_diff} _r - - - - - .. math:: - - src(x',y')_g- \texttt{lo\_diff} _g<=src(x,y)_g<=src(x',y')_g+ \texttt{up\_diff} _g - - - - - .. math:: - - src(x',y')_b- \texttt{lo\_diff} _b<=src(x,y)_b<=src(x',y')_b+ \texttt{up\_diff} _b - - - - -* color image, fixed range - - - .. math:: - - src(seed.x,seed.y)_r- \texttt{lo\_diff} _r<=src(x,y)_r<=src(seed.x,seed.y)_r+ \texttt{up\_diff} _r - - - - - .. math:: - - src(seed.x,seed.y)_g- \texttt{lo\_diff} _g<=src(x,y)_g<=src(seed.x,seed.y)_g+ \texttt{up\_diff} _g - - - - - .. math:: - - src(seed.x,seed.y)_b- \texttt{lo\_diff} _b<=src(x,y)_b<=src(seed.x,seed.y)_b+ \texttt{up\_diff} _b - - - - -where -:math:`src(x',y')` -is the value of one of pixel neighbors. That is, to be added to the connected component, a pixel's color/brightness should be close enough to the: - - - - -* - color/brightness of one of its neighbors that are already referred to the connected component in the case of floating range - - - -* - color/brightness of the seed point in the case of fixed range. - - - -.. index:: Inpaint - -.. _Inpaint: - -Inpaint -------- - - - - -.. function:: Inpaint(src,mask,dst,inpaintRadius,flags) -> None - - Inpaints the selected region in the image. - - - - - - - :param src: The input 8-bit 1-channel or 3-channel image. - - :type src: :class:`CvArr` - - - :param mask: The inpainting mask, 8-bit 1-channel image. Non-zero pixels indicate the area that needs to be inpainted. - - :type mask: :class:`CvArr` - - - :param dst: The output image of the same format and the same size as input. - - :type dst: :class:`CvArr` - - - :param inpaintRadius: The radius of circlular neighborhood of each point inpainted that is considered by the algorithm. - - :type inpaintRadius: float - - - :param flags: The inpainting method, one of the following: - - * **CV_INPAINT_NS** Navier-Stokes based method. - - * **CV_INPAINT_TELEA** The method by Alexandru Telea Telea04 - - - - :type flags: int - - - -The function reconstructs the selected image area from the pixel near the area boundary. The function may be used to remove dust and scratches from a scanned photo, or to remove undesirable objects from still images or video. - - -.. index:: Integral - -.. _Integral: - -Integral --------- - - - - -.. function:: Integral(image,sum,sqsum=NULL,tiltedSum=NULL)-> None - - Calculates the integral of an image. - - - - - - - :param image: The source image, :math:`W\times H` , 8-bit or floating-point (32f or 64f) - - :type image: :class:`CvArr` - - - :param sum: The integral image, :math:`(W+1)\times (H+1)` , 32-bit integer or double precision floating-point (64f) - - :type sum: :class:`CvArr` - - - :param sqsum: The integral image for squared pixel values, :math:`(W+1)\times (H+1)` , double precision floating-point (64f) - - :type sqsum: :class:`CvArr` - - - :param tiltedSum: The integral for the image rotated by 45 degrees, :math:`(W+1)\times (H+1)` , the same data type as ``sum`` - - :type tiltedSum: :class:`CvArr` - - - -The function calculates one or more integral images for the source image as following: - - - -.. math:: - - \texttt{sum} (X,Y) = \sum _{x None - - Does meanshift image segmentation - - - - - - - :param src: The source 8-bit, 3-channel image. - - :type src: :class:`CvArr` - - - :param dst: The destination image of the same format and the same size as the source. - - :type dst: :class:`CvArr` - - - :param sp: The spatial window radius. - - :type sp: float - - - :param sr: The color window radius. - - :type sr: float - - - :param max_level: Maximum level of the pyramid for the segmentation. - - :type max_level: int - - - :param termcrit: Termination criteria: when to stop meanshift iterations. - - :type termcrit: :class:`CvTermCriteria` - - - -The function implements the filtering -stage of meanshift segmentation, that is, the output of the function is -the filtered "posterized" image with color gradients and fine-grain -texture flattened. At every pixel -:math:`(X,Y)` -of the input image (or -down-sized input image, see below) the function executes meanshift -iterations, that is, the pixel -:math:`(X,Y)` -neighborhood in the joint -space-color hyperspace is considered: - - - -.. math:: - - (x,y): X- \texttt{sp} \le x \le X+ \texttt{sp} , Y- \texttt{sp} \le y \le Y+ \texttt{sp} , ||(R,G,B)-(r,g,b)|| \le \texttt{sr} - - -where -``(R,G,B)`` -and -``(r,g,b)`` -are the vectors of color components at -``(X,Y)`` -and -``(x,y)`` -, respectively (though, the algorithm does not depend on the color space used, so any 3-component color space can be used instead). Over the neighborhood the average spatial value -``(X',Y')`` -and average color vector -``(R',G',B')`` -are found and they act as the neighborhood center on the next iteration: - -:math:`(X,Y)~(X',Y'), (R,G,B)~(R',G',B').` -After the iterations over, the color components of the initial pixel (that is, the pixel from where the iterations started) are set to the final value (average color at the last iteration): - -:math:`I(X,Y) <- (R*,G*,B*)` -Then -:math:`\texttt{max\_level}>0` -, the gaussian pyramid of -:math:`\texttt{max\_level}+1` -levels is built, and the above procedure is run -on the smallest layer. After that, the results are propagated to the -larger layer and the iterations are run again only on those pixels where -the layer colors differ much ( -:math:`>\texttt{sr}` -) from the lower-resolution -layer, that is, the boundaries of the color regions are clarified. Note, -that the results will be actually different from the ones obtained by -running the meanshift procedure on the whole original image (i.e. when -:math:`\texttt{max\_level}==0` -). - - -.. index:: PyrSegmentation - -.. _PyrSegmentation: - -PyrSegmentation ---------------- - - - - -.. function:: PyrSegmentation(src,dst,storage,level,threshold1,threshold2)-> comp - - Implements image segmentation by pyramids. - - - - - - - :param src: The source image - - :type src: :class:`IplImage` - - - :param dst: The destination image - - :type dst: :class:`IplImage` - - - :param storage: Storage; stores the resulting sequence of connected components - - :type storage: :class:`CvMemStorage` - - - :param comp: Pointer to the output sequence of the segmented components - - :type comp: :class:`CvSeq` - - - :param level: Maximum level of the pyramid for the segmentation - - :type level: int - - - :param threshold1: Error threshold for establishing the links - - :type threshold1: float - - - :param threshold2: Error threshold for the segments clustering - - :type threshold2: float - - - -The function implements image segmentation by pyramids. The pyramid builds up to the level -``level`` -. The links between any pixel -``a`` -on level -``i`` -and its candidate father pixel -``b`` -on the adjacent level are established if -:math:`p(c(a),c(b)) None - - Applies a fixed-level threshold to array elements. - - - - - - - :param src: Source array (single-channel, 8-bit or 32-bit floating point) - - :type src: :class:`CvArr` - - - :param dst: Destination array; must be either the same type as ``src`` or 8-bit - - :type dst: :class:`CvArr` - - - :param threshold: Threshold value - - :type threshold: float - - - :param maxValue: Maximum value to use with ``CV_THRESH_BINARY`` and ``CV_THRESH_BINARY_INV`` thresholding types - - :type maxValue: float - - - :param thresholdType: Thresholding type (see the discussion) - - :type thresholdType: int - - - -The function applies fixed-level thresholding -to a single-channel array. The function is typically used to get a -bi-level (binary) image out of a grayscale image ( -:ref:`CmpS` -could -be also used for this purpose) or for removing a noise, i.e. filtering -out pixels with too small or too large values. There are several -types of thresholding that the function supports that are determined by -``thresholdType`` -: - - - - - * **CV_THRESH_BINARY** - - .. math:: - - \texttt{dst} (x,y) = \fork{\texttt{maxValue}}{if $\texttt{src}(x,y) > \texttt{threshold}$}{0}{otherwise} - - - - - * **CV_THRESH_BINARY_INV** - - .. math:: - - \texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{threshold}$}{\texttt{maxValue}}{otherwise} - - - - - * **CV_THRESH_TRUNC** - - .. math:: - - \texttt{dst} (x,y) = \fork{\texttt{threshold}}{if $\texttt{src}(x,y) > \texttt{threshold}$}{\texttt{src}(x,y)}{otherwise} - - - - - * **CV_THRESH_TOZERO** - - .. math:: - - \texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if $\texttt{src}(x,y) > \texttt{threshold}$}{0}{otherwise} - - - - - * **CV_THRESH_TOZERO_INV** - - .. math:: - - \texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{threshold}$}{\texttt{src}(x,y)}{otherwise} - - - - - -Also, the special value -``CV_THRESH_OTSU`` -may be combined with -one of the above values. In this case the function determines the optimal threshold -value using Otsu's algorithm and uses it instead of the specified -``thresh`` -. -The function returns the computed threshold value. -Currently, Otsu's method is implemented only for 8-bit images. - - - -.. image:: ../pics/threshold.png - - - diff --git a/doc/opencv1/py/imgproc_motion_analysis_and_object_tracking.rst b/doc/opencv1/py/imgproc_motion_analysis_and_object_tracking.rst deleted file mode 100644 index 378ff6ddc5..0000000000 --- a/doc/opencv1/py/imgproc_motion_analysis_and_object_tracking.rst +++ /dev/null @@ -1,216 +0,0 @@ -Motion Analysis and Object Tracking -=================================== - -.. highlight:: python - - - -.. index:: Acc - -.. _Acc: - -Acc ---- - - - - -.. function:: Acc(image,sum,mask=NULL)-> None - - Adds a frame to an accumulator. - - - - - - - :param image: Input image, 1- or 3-channel, 8-bit or 32-bit floating point. (each channel of multi-channel image is processed independently) - - :type image: :class:`CvArr` - - - :param sum: Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point - - :type sum: :class:`CvArr` - - - :param mask: Optional operation mask - - :type mask: :class:`CvArr` - - - -The function adds the whole image -``image`` -or its selected region to the accumulator -``sum`` -: - - - -.. math:: - - \texttt{sum} (x,y) \leftarrow \texttt{sum} (x,y) + \texttt{image} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 - - - -.. index:: MultiplyAcc - -.. _MultiplyAcc: - -MultiplyAcc ------------ - - - - -.. function:: MultiplyAcc(image1,image2,acc,mask=NULL)-> None - - Adds the product of two input images to the accumulator. - - - - - - - :param image1: First input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently) - - :type image1: :class:`CvArr` - - - :param image2: Second input image, the same format as the first one - - :type image2: :class:`CvArr` - - - :param acc: Accumulator with the same number of channels as input images, 32-bit or 64-bit floating-point - - :type acc: :class:`CvArr` - - - :param mask: Optional operation mask - - :type mask: :class:`CvArr` - - - -The function adds the product of 2 images or their selected regions to the accumulator -``acc`` -: - - - -.. math:: - - \texttt{acc} (x,y) \leftarrow \texttt{acc} (x,y) + \texttt{image1} (x,y) \cdot \texttt{image2} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 - - - -.. index:: RunningAvg - -.. _RunningAvg: - -RunningAvg ----------- - - - - -.. function:: RunningAvg(image,acc,alpha,mask=NULL)-> None - - Updates the running average. - - - - - - - :param image: Input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently) - - :type image: :class:`CvArr` - - - :param acc: Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point - - :type acc: :class:`CvArr` - - - :param alpha: Weight of input image - - :type alpha: float - - - :param mask: Optional operation mask - - :type mask: :class:`CvArr` - - - -The function calculates the weighted sum of the input image -``image`` -and the accumulator -``acc`` -so that -``acc`` -becomes a running average of frame sequence: - - - -.. math:: - - \texttt{acc} (x,y) \leftarrow (1- \alpha ) \cdot \texttt{acc} (x,y) + \alpha \cdot \texttt{image} (x,y) \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 - - -where -:math:`\alpha` -regulates the update speed (how fast the accumulator forgets about previous frames). - - -.. index:: SquareAcc - -.. _SquareAcc: - -SquareAcc ---------- - - - - -.. function:: SquareAcc(image,sqsum,mask=NULL)-> None - - Adds the square of the source image to the accumulator. - - - - - - - :param image: Input image, 1- or 3-channel, 8-bit or 32-bit floating point (each channel of multi-channel image is processed independently) - - :type image: :class:`CvArr` - - - :param sqsum: Accumulator with the same number of channels as input image, 32-bit or 64-bit floating-point - - :type sqsum: :class:`CvArr` - - - :param mask: Optional operation mask - - :type mask: :class:`CvArr` - - - -The function adds the input image -``image`` -or its selected region, raised to power 2, to the accumulator -``sqsum`` -: - - - -.. math:: - - \texttt{sqsum} (x,y) \leftarrow \texttt{sqsum} (x,y) + \texttt{image} (x,y)^2 \quad \text{if} \quad \texttt{mask} (x,y) \ne 0 - - diff --git a/doc/opencv1/py/imgproc_object_detection.rst b/doc/opencv1/py/imgproc_object_detection.rst deleted file mode 100644 index bd7e5577c6..0000000000 --- a/doc/opencv1/py/imgproc_object_detection.rst +++ /dev/null @@ -1,155 +0,0 @@ -Object Detection -================ - -.. highlight:: python - - - -.. index:: MatchTemplate - -.. _MatchTemplate: - -MatchTemplate -------------- - - - - -.. function:: MatchTemplate(image,templ,result,method)-> None - - Compares a template against overlapped image regions. - - - - - - - :param image: Image where the search is running; should be 8-bit or 32-bit floating-point - - :type image: :class:`CvArr` - - - :param templ: Searched template; must be not greater than the source image and the same data type as the image - - :type templ: :class:`CvArr` - - - :param result: A map of comparison results; single-channel 32-bit floating-point. - If ``image`` is :math:`W \times H` and ``templ`` is :math:`w \times h` then ``result`` must be :math:`(W-w+1) \times (H-h+1)` - - :type result: :class:`CvArr` - - - :param method: Specifies the way the template must be compared with the image regions (see below) - - :type method: int - - - -The function is similar to -:ref:`CalcBackProjectPatch` -. It slides through -``image`` -, compares the -overlapped patches of size -:math:`w \times h` -against -``templ`` -using the specified method and stores the comparison results to -``result`` -. Here are the formulas for the different comparison -methods one may use ( -:math:`I` -denotes -``image`` -, -:math:`T` -``template`` -, -:math:`R` -``result`` -). The summation is done over template and/or the -image patch: -:math:`x' = 0...w-1, y' = 0...h-1` - - - - -* method=CV\_TM\_SQDIFF - - - .. math:: - - R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2 - - - - -* method=CV\_TM\_SQDIFF\_NORMED - - - .. math:: - - R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}} - - - - -* method=CV\_TM\_CCORR - - - .. math:: - - R(x,y)= \sum _{x',y'} (T(x',y') \cdot I(x+x',y+y')) - - - - -* method=CV\_TM\_CCORR\_NORMED - - - .. math:: - - R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}} - - - - -* method=CV\_TM\_CCOEFF - - - .. math:: - - R(x,y)= \sum _{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) - - - where - - - .. math:: - - \begin{array}{l} T'(x',y')=T(x',y') - 1/(w \cdot h) \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w \cdot h) \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array} - - - - -* method=CV\_TM\_CCOEFF\_NORMED - - - .. math:: - - R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} } - - - - -After the function finishes the comparison, the best matches can be found as global minimums ( -``CV_TM_SQDIFF`` -) or maximums ( -``CV_TM_CCORR`` -and -``CV_TM_CCOEFF`` -) using the -:ref:`MinMaxLoc` -function. In the case of a color image, template summation in the numerator and each sum in the denominator is done over all of the channels (and separate mean values are used for each channel). - diff --git a/doc/opencv1/py/imgproc_planar_subdivisions.rst b/doc/opencv1/py/imgproc_planar_subdivisions.rst deleted file mode 100644 index f39e658765..0000000000 --- a/doc/opencv1/py/imgproc_planar_subdivisions.rst +++ /dev/null @@ -1,561 +0,0 @@ -Planar Subdivisions -=================== - -.. highlight:: python - - - -.. index:: CvSubdiv2D - -.. _CvSubdiv2D: - -CvSubdiv2D ----------- - - - -.. class:: CvSubdiv2D - - - -Planar subdivision. - - - - - - .. attribute:: edges - - - - A :ref:`CvSet` of :ref:`CvSubdiv2DEdge` - - - -Planar subdivision is the subdivision of a plane into a set of -non-overlapped regions (facets) that cover the whole plane. The above -structure describes a subdivision built on a 2d point set, where the points -are linked together and form a planar graph, which, together with a few -edges connecting the exterior subdivision points (namely, convex hull points) -with infinity, subdivides a plane into facets by its edges. - -For every subdivision there exists a dual subdivision in which facets and -points (subdivision vertices) swap their roles, that is, a facet is -treated as a vertex (called a virtual point below) of the dual subdivision and -the original subdivision vertices become facets. On the picture below -original subdivision is marked with solid lines and dual subdivision -with dotted lines. - - - -.. image:: ../pics/subdiv.png - - - -OpenCV subdivides a plane into triangles using Delaunay's -algorithm. Subdivision is built iteratively starting from a dummy -triangle that includes all the subdivision points for sure. In this -case the dual subdivision is a Voronoi diagram of the input 2d point set. The -subdivisions can be used for the 3d piece-wise transformation of a plane, -morphing, fast location of points on the plane, building special graphs -(such as NNG,RNG) and so forth. - - -.. index:: CvSubdiv2DPoint - -.. _CvSubdiv2DPoint: - -CvSubdiv2DPoint ---------------- - - - -.. class:: CvSubdiv2DPoint - - - -Point of original or dual subdivision. - - - - - - .. attribute:: first - - - - A connected :ref:`CvSubdiv2DEdge` - - - - .. attribute:: pt - - - - Position, as a :ref:`CvPoint2D32f` - - - - -.. index:: CalcSubdivVoronoi2D - -.. _CalcSubdivVoronoi2D: - -CalcSubdivVoronoi2D -------------------- - - - - -.. function:: CalcSubdivVoronoi2D(subdiv)-> None - - Calculates the coordinates of Voronoi diagram cells. - - - - - - - :param subdiv: Delaunay subdivision, in which all the points are already added - - :type subdiv: :class:`CvSubdiv2D` - - - -The function calculates the coordinates -of virtual points. All virtual points corresponding to some vertex of the -original subdivision form (when connected together) a boundary of the Voronoi -cell at that point. - - -.. index:: ClearSubdivVoronoi2D - -.. _ClearSubdivVoronoi2D: - -ClearSubdivVoronoi2D --------------------- - - - - -.. function:: ClearSubdivVoronoi2D(subdiv)-> None - - Removes all virtual points. - - - - - - - :param subdiv: Delaunay subdivision - - :type subdiv: :class:`CvSubdiv2D` - - - -The function removes all of the virtual points. It -is called internally in -:ref:`CalcSubdivVoronoi2D` -if the subdivision -was modified after previous call to the function. - - - -.. index:: CreateSubdivDelaunay2D - -.. _CreateSubdivDelaunay2D: - -CreateSubdivDelaunay2D ----------------------- - - - - -.. function:: CreateSubdivDelaunay2D(rect,storage)-> delaunay_triangulation - - Creates an empty Delaunay triangulation. - - - - - - - :param rect: Rectangle that includes all of the 2d points that are to be added to the subdivision - - :type rect: :class:`CvRect` - - - :param storage: Container for subdivision - - :type storage: :class:`CvMemStorage` - - - -The function creates an empty Delaunay -subdivision, where 2d points can be added using the function -:ref:`SubdivDelaunay2DInsert` -. All of the points to be added must be within -the specified rectangle, otherwise a runtime error will be raised. - -Note that the triangulation is a single large triangle that covers the given rectangle. Hence the three vertices of this triangle are outside the rectangle -``rect`` -. - - -.. index:: FindNearestPoint2D - -.. _FindNearestPoint2D: - -FindNearestPoint2D ------------------- - - - - -.. function:: FindNearestPoint2D(subdiv,pt)-> point - - Finds the closest subdivision vertex to the given point. - - - - - - - :param subdiv: Delaunay or another subdivision - - :type subdiv: :class:`CvSubdiv2D` - - - :param pt: Input point - - :type pt: :class:`CvPoint2D32f` - - - -The function is another function that -locates the input point within the subdivision. It finds the subdivision vertex that -is the closest to the input point. It is not necessarily one of vertices -of the facet containing the input point, though the facet (located using -:ref:`Subdiv2DLocate` -) is used as a starting -point. The function returns a pointer to the found subdivision vertex. - - -.. index:: Subdiv2DEdgeDst - -.. _Subdiv2DEdgeDst: - -Subdiv2DEdgeDst ---------------- - - - - -.. function:: Subdiv2DEdgeDst(edge)-> point - - Returns the edge destination. - - - - - - - :param edge: Subdivision edge (not a quad-edge) - - :type edge: :class:`CvSubdiv2DEdge` - - - -The function returns the edge destination. The -returned pointer may be NULL if the edge is from dual subdivision and -the virtual point coordinates are not calculated yet. The virtual points -can be calculated using the function -:ref:`CalcSubdivVoronoi2D` -. - - -.. index:: Subdiv2DGetEdge - -.. _Subdiv2DGetEdge: - -Subdiv2DGetEdge ---------------- - - - - -.. function:: Subdiv2DGetEdge(edge,type)-> CvSubdiv2DEdge - - Returns one of the edges related to the given edge. - - - - - - - :param edge: Subdivision edge (not a quad-edge) - - :type edge: :class:`CvSubdiv2DEdge` - - - :param type: Specifies which of the related edges to return, one of the following: - - :type type: :class:`CvNextEdgeType` - - - - - * **CV_NEXT_AROUND_ORG** next around the edge origin ( ``eOnext`` on the picture below if ``e`` is the input edge) - - - * **CV_NEXT_AROUND_DST** next around the edge vertex ( ``eDnext`` ) - - - * **CV_PREV_AROUND_ORG** previous around the edge origin (reversed ``eRnext`` ) - - - * **CV_PREV_AROUND_DST** previous around the edge destination (reversed ``eLnext`` ) - - - * **CV_NEXT_AROUND_LEFT** next around the left facet ( ``eLnext`` ) - - - * **CV_NEXT_AROUND_RIGHT** next around the right facet ( ``eRnext`` ) - - - * **CV_PREV_AROUND_LEFT** previous around the left facet (reversed ``eOnext`` ) - - - * **CV_PREV_AROUND_RIGHT** previous around the right facet (reversed ``eDnext`` ) - - - - - - - -.. image:: ../pics/quadedge.png - - - -The function returns one of the edges related to the input edge. - - -.. index:: Subdiv2DNextEdge - -.. _Subdiv2DNextEdge: - -Subdiv2DNextEdge ----------------- - - - - -.. function:: Subdiv2DNextEdge(edge)-> CvSubdiv2DEdge - - Returns next edge around the edge origin - - - - - - - :param edge: Subdivision edge (not a quad-edge) - - :type edge: :class:`CvSubdiv2DEdge` - - - - - -.. image:: ../pics/quadedge.png - - - -The function returns the next edge around the edge origin: -``eOnext`` -on the picture above if -``e`` -is the input edge) - - -.. index:: Subdiv2DLocate - -.. _Subdiv2DLocate: - -Subdiv2DLocate --------------- - - - - -.. function:: Subdiv2DLocate(subdiv, pt) -> (loc, where) - - Returns the location of a point within a Delaunay triangulation. - - - - - - - :param subdiv: Delaunay or another subdivision - - :type subdiv: :class:`CvSubdiv2D` - - - :param pt: The point to locate - - :type pt: :class:`CvPoint2D32f` - - - :param loc: The location of the point within the triangulation - - :type loc: int - - - :param where: The edge or vertex. See below. - - :type where: :class:`CvSubdiv2DEdge`, :class:`CvSubdiv2DPoint` - - - -The function locates the input point within the subdivision. There are 5 cases: - - - - - -* - The point falls into some facet. - ``loc`` - is - ``CV_PTLOC_INSIDE`` - and - ``where`` - is one of edges of the facet. - - - -* - The point falls onto the edge. - ``loc`` - is - ``CV_PTLOC_ON_EDGE`` - and - ``where`` - is the edge. - - - -* - The point coincides with one of the subdivision vertices. - ``loc`` - is - ``CV_PTLOC_VERTEX`` - and - ``where`` - is the vertex. - - - -* - The point is outside the subdivsion reference rectangle. - ``loc`` - is - ``CV_PTLOC_OUTSIDE_RECT`` - and - ``where`` - is None. - - - -* - One of input arguments is invalid. The function raises an exception. - - - -.. index:: Subdiv2DRotateEdge - -.. _Subdiv2DRotateEdge: - -Subdiv2DRotateEdge ------------------- - - - - -.. function:: Subdiv2DRotateEdge(edge,rotate)-> CvSubdiv2DEdge - - Returns another edge of the same quad-edge. - - - - - - - :param edge: Subdivision edge (not a quad-edge) - - :type edge: :class:`CvSubdiv2DEdge` - - - :param rotate: Specifies which of the edges of the same quad-edge as the input one to return, one of the following: - - - * **0** the input edge ( ``e`` on the picture below if ``e`` is the input edge) - - - * **1** the rotated edge ( ``eRot`` ) - - - * **2** the reversed edge (reversed ``e`` (in green)) - - - * **3** the reversed rotated edge (reversed ``eRot`` (in green)) - - - - :type rotate: int - - - - - -.. image:: ../pics/quadedge.png - - - -The function returns one of the edges of the same quad-edge as the input edge. - - -.. index:: SubdivDelaunay2DInsert - -.. _SubdivDelaunay2DInsert: - -SubdivDelaunay2DInsert ----------------------- - - - - -.. function:: SubdivDelaunay2DInsert(subdiv,pt)-> point - - Inserts a single point into a Delaunay triangulation. - - - - - - - :param subdiv: Delaunay subdivision created by the function :ref:`CreateSubdivDelaunay2D` - - :type subdiv: :class:`CvSubdiv2D` - - - :param pt: Inserted point - - :type pt: :class:`CvPoint2D32f` - - - -The function inserts a single point into a subdivision and modifies the subdivision topology appropriately. If a point with the same coordinates exists already, no new point is added. The function returns a pointer to the allocated point. No virtual point coordinates are calculated at this stage. - diff --git a/doc/opencv1/py/imgproc_structural_analysis_and_shape_descriptors.rst b/doc/opencv1/py/imgproc_structural_analysis_and_shape_descriptors.rst deleted file mode 100644 index 16a9ee97f0..0000000000 --- a/doc/opencv1/py/imgproc_structural_analysis_and_shape_descriptors.rst +++ /dev/null @@ -1,1484 +0,0 @@ -Structural Analysis and Shape Descriptors -========================================= - -.. highlight:: python - - - -.. index:: ApproxChains - -.. _ApproxChains: - -ApproxChains ------------- - - - - -.. function:: ApproxChains(src_seq,storage,method=CV_CHAIN_APPROX_SIMPLE,parameter=0,minimal_perimeter=0,recursive=0)-> chains - - Approximates Freeman chain(s) with a polygonal curve. - - - - - - - :param src_seq: Pointer to the chain that can refer to other chains - - :type src_seq: :class:`CvSeq` - - - :param storage: Storage location for the resulting polylines - - :type storage: :class:`CvMemStorage` - - - :param method: Approximation method (see the description of the function :ref:`FindContours` ) - - :type method: int - - - :param parameter: Method parameter (not used now) - - :type parameter: float - - - :param minimal_perimeter: Approximates only those contours whose perimeters are not less than ``minimal_perimeter`` . Other chains are removed from the resulting structure - - :type minimal_perimeter: int - - - :param recursive: If not 0, the function approximates all chains that access can be obtained to from ``src_seq`` by using the ``h_next`` or ``v_next links`` . If 0, the single chain is approximated - - :type recursive: int - - - -This is a stand-alone approximation routine. The function -``cvApproxChains`` -works exactly in the same way as -:ref:`FindContours` -with the corresponding approximation flag. The function returns pointer to the first resultant contour. Other approximated contours, if any, can be accessed via the -``v_next`` -or -``h_next`` -fields of the returned structure. - - -.. index:: ApproxPoly - -.. _ApproxPoly: - -ApproxPoly ----------- - - - - -.. function:: -ApproxPoly(src_seq, storage, method, parameter=0, parameter2=0) -> sequence - - - Approximates polygonal curve(s) with the specified precision. - - - - - - - :param src_seq: Sequence of an array of points - - :type src_seq: :class:`CvArr` or :class:`CvSeq` - - - :param storage: Container for the approximated contours. If it is NULL, the input sequences' storage is used - - :type storage: :class:`CvMemStorage` - - - :param method: Approximation method; only ``CV_POLY_APPROX_DP`` is supported, that corresponds to the Douglas-Peucker algorithm - - :type method: int - - - :param parameter: Method-specific parameter; in the case of ``CV_POLY_APPROX_DP`` it is a desired approximation accuracy - - :type parameter: float - - - :param parameter2: If case if ``src_seq`` is a sequence, the parameter determines whether the single sequence should be approximated or all sequences on the same level or below ``src_seq`` (see :ref:`FindContours` for description of hierarchical contour structures). If ``src_seq`` is an array CvMat* of points, the parameter specifies whether the curve is closed ( ``parameter2`` !=0) or not ( ``parameter2`` =0) - - :type parameter2: int - - - -The function approximates one or more curves and -returns the approximation result[s]. In the case of multiple curves, -the resultant tree will have the same structure as the input one (1:1 -correspondence). - - -.. index:: ArcLength - -.. _ArcLength: - -ArcLength ---------- - - - - -.. function:: ArcLength(curve,slice=CV_WHOLE_SEQ,isClosed=-1)-> double - - Calculates the contour perimeter or the curve length. - - - - - - - :param curve: Sequence or array of the curve points - - :type curve: :class:`CvArr` or :class:`CvSeq` - - - :param slice: Starting and ending points of the curve, by default, the whole curve length is calculated - - :type slice: :class:`CvSlice` - - - :param isClosed: Indicates whether the curve is closed or not. There are 3 cases: - - - - * :math:`\texttt{isClosed}=0` the curve is assumed to be unclosed. - - - * :math:`\texttt{isClosed}>0` the curve is assumed to be closed. - - - * :math:`\texttt{isClosed}<0` if curve is sequence, the flag ``CV_SEQ_FLAG_CLOSED`` of ``((CvSeq*)curve)->flags`` is checked to determine if the curve is closed or not, otherwise (curve is represented by array (CvMat*) of points) it is assumed to be unclosed. - - - :type isClosed: int - - - -The function calculates the length or curve as the sum of lengths of segments between subsequent points - - -.. index:: BoundingRect - -.. _BoundingRect: - -BoundingRect ------------- - - - - -.. function:: BoundingRect(points,update=0)-> CvRect - - Calculates the up-right bounding rectangle of a point set. - - - - - - - :param points: 2D point set, either a sequence or vector ( ``CvMat`` ) of points - - :type points: :class:`CvArr` or :class:`CvSeq` - - - :param update: The update flag. See below. - - :type update: int - - - -The function returns the up-right bounding rectangle for a 2d point set. -Here is the list of possible combination of the flag values and type of -``points`` -: - - -.. table:: - - ====== ========================= ======================================================================================================= - update points action \ - ====== ========================= ======================================================================================================= - 0 ``CvContour*`` the bounding rectangle is not calculated, but it is taken from ``rect`` field of the contour header. \ - 1 ``CvContour*`` the bounding rectangle is calculated and written to ``rect`` field of the contour header. \ - 0 ``CvSeq*`` or ``CvMat*`` the bounding rectangle is calculated and returned. \ - 1 ``CvSeq*`` or ``CvMat*`` runtime error is raised. \ - ====== ========================= ======================================================================================================= - - -.. index:: BoxPoints - -.. _BoxPoints: - -BoxPoints ---------- - - - - -.. function:: BoxPoints(box)-> points - - Finds the box vertices. - - - - - - - :param box: Box - - :type box: :class:`CvBox2D` - - - :param points: Array of vertices - - :type points: :class:`CvPoint2D32f_4` - - - -The function calculates the vertices of the input 2d box. - - -.. index:: CalcPGH - -.. _CalcPGH: - -CalcPGH -------- - - - - -.. function:: CalcPGH(contour,hist)-> None - - Calculates a pair-wise geometrical histogram for a contour. - - - - - - - :param contour: Input contour. Currently, only integer point coordinates are allowed - - - :param hist: Calculated histogram; must be two-dimensional - - - -The function calculates a -2D pair-wise geometrical histogram (PGH), described in -:ref:`Iivarinen97` -for the contour. The algorithm considers every pair of contour -edges. The angle between the edges and the minimum/maximum distances -are determined for every pair. To do this each of the edges in turn -is taken as the base, while the function loops through all the other -edges. When the base edge and any other edge are considered, the minimum -and maximum distances from the points on the non-base edge and line of -the base edge are selected. The angle between the edges defines the row -of the histogram in which all the bins that correspond to the distance -between the calculated minimum and maximum distances are incremented -(that is, the histogram is transposed relatively to the -:ref:`Iivarninen97` -definition). The histogram can be used for contour matching. - - -.. index:: CalcEMD2 - -.. _CalcEMD2: - -CalcEMD2 --------- - - - - -.. function:: CalcEMD2(signature1, signature2, distance_type, distance_func = None, cost_matrix=None, flow=None, lower_bound=None, userdata = None) -> float - - Computes the "minimal work" distance between two weighted point configurations. - - - - - - - :param signature1: First signature, a :math:`\texttt{size1}\times \texttt{dims}+1` floating-point matrix. Each row stores the point weight followed by the point coordinates. The matrix is allowed to have a single column (weights only) if the user-defined cost matrix is used - - :type signature1: :class:`CvArr` - - - :param signature2: Second signature of the same format as ``signature1`` , though the number of rows may be different. The total weights may be different, in this case an extra "dummy" point is added to either ``signature1`` or ``signature2`` - - :type signature2: :class:`CvArr` - - - :param distance_type: Metrics used; ``CV_DIST_L1, CV_DIST_L2`` , and ``CV_DIST_C`` stand for one of the standard metrics; ``CV_DIST_USER`` means that a user-defined function ``distance_func`` or pre-calculated ``cost_matrix`` is used - - :type distance_type: int - - - :param distance_func: The user-supplied distance function. It takes coordinates of two points ``pt0`` and ``pt1`` , and returns the distance between the points, with sigature `` - func(pt0, pt1, userdata) -> float`` - - :type distance_func: :class:`PyCallableObject` - - - :param cost_matrix: The user-defined :math:`\texttt{size1}\times \texttt{size2}` cost matrix. At least one of ``cost_matrix`` and ``distance_func`` must be NULL. Also, if a cost matrix is used, lower boundary (see below) can not be calculated, because it needs a metric function - - :type cost_matrix: :class:`CvArr` - - - :param flow: The resultant :math:`\texttt{size1} \times \texttt{size2}` flow matrix: :math:`\texttt{flow}_{i,j}` is a flow from :math:`i` th point of ``signature1`` to :math:`j` th point of ``signature2`` - - :type flow: :class:`CvArr` - - - :param lower_bound: Optional input/output parameter: lower boundary of distance between the two signatures that is a distance between mass centers. The lower boundary may not be calculated if the user-defined cost matrix is used, the total weights of point configurations are not equal, or if the signatures consist of weights only (i.e. the signature matrices have a single column). The user **must** initialize ``*lower_bound`` . If the calculated distance between mass centers is greater or equal to ``*lower_bound`` (it means that the signatures are far enough) the function does not calculate EMD. In any case ``*lower_bound`` is set to the calculated distance between mass centers on return. Thus, if user wants to calculate both distance between mass centers and EMD, ``*lower_bound`` should be set to 0 - - :type lower_bound: float - - - :param userdata: Pointer to optional data that is passed into the user-defined distance function - - :type userdata: object - - - -The function computes the earth mover distance and/or -a lower boundary of the distance between the two weighted point -configurations. One of the applications described in -:ref:`RubnerSept98` -is -multi-dimensional histogram comparison for image retrieval. EMD is a a -transportation problem that is solved using some modification of a simplex -algorithm, thus the complexity is exponential in the worst case, though, on average -it is much faster. In the case of a real metric the lower boundary -can be calculated even faster (using linear-time algorithm) and it can -be used to determine roughly whether the two signatures are far enough -so that they cannot relate to the same object. - - -.. index:: CheckContourConvexity - -.. _CheckContourConvexity: - -CheckContourConvexity ---------------------- - - - - -.. function:: CheckContourConvexity(contour)-> int - - Tests contour convexity. - - - - - - - :param contour: Tested contour (sequence or array of points) - - :type contour: :class:`CvArr` or :class:`CvSeq` - - - -The function tests whether the input contour is convex or not. The contour must be simple, without self-intersections. - - -.. index:: CvConvexityDefect - -.. _CvConvexityDefect: - -CvConvexityDefect ------------------ - - - -.. class:: CvConvexityDefect - - - -A single contour convexity defect, represented by a tuple -``(start, end, depthpoint, depth)`` -. - - - - - - .. attribute:: start - - - - (x, y) point of the contour where the defect begins - - - - .. attribute:: end - - - - (x, y) point of the contour where the defect ends - - - - .. attribute:: depthpoint - - - - (x, y) point farthest from the convex hull point within the defect - - - - .. attribute:: depth - - - - distance between the farthest point and the convex hull - - - - - -.. image:: ../pics/defects.png - - - - -.. index:: ContourArea - -.. _ContourArea: - -ContourArea ------------ - - - - -.. function:: ContourArea(contour,slice=CV_WHOLE_SEQ)-> double - - Calculates the area of a whole contour or a contour section. - - - - - - - :param contour: Contour (sequence or array of vertices) - - :type contour: :class:`CvArr` or :class:`CvSeq` - - - :param slice: Starting and ending points of the contour section of interest, by default, the area of the whole contour is calculated - - :type slice: :class:`CvSlice` - - - -The function calculates the area of a whole contour -or a contour section. In the latter case the total area bounded by the -contour arc and the chord connecting the 2 selected points is calculated -as shown on the picture below: - - - -.. image:: ../pics/contoursecarea.png - - - -Orientation of the contour affects the area sign, thus the function may return a -*negative* -result. Use the -``fabs()`` -function from C runtime to get the absolute value of the area. - - -.. index:: ContourFromContourTree - -.. _ContourFromContourTree: - -ContourFromContourTree ----------------------- - - - - -.. function:: ContourFromContourTree(tree,storage,criteria)-> contour - - Restores a contour from the tree. - - - - - - - :param tree: Contour tree - - - :param storage: Container for the reconstructed contour - - - :param criteria: Criteria, where to stop reconstruction - - - -The function restores the contour from its binary tree representation. The parameter -``criteria`` -determines the accuracy and/or the number of tree levels used for reconstruction, so it is possible to build an approximated contour. The function returns the reconstructed contour. - - -.. index:: ConvexHull2 - -.. _ConvexHull2: - -ConvexHull2 ------------ - - - - -.. function:: ConvexHull2(points,storage,orientation=CV_CLOCKWISE,return_points=0)-> convex_hull - - Finds the convex hull of a point set. - - - - - - - :param points: Sequence or array of 2D points with 32-bit integer or floating-point coordinates - - :type points: :class:`CvArr` or :class:`CvSeq` - - - :param storage: The destination array (CvMat*) or memory storage (CvMemStorage*) that will store the convex hull. If it is an array, it should be 1d and have the same number of elements as the input array/sequence. On output the header is modified as to truncate the array down to the hull size. If ``storage`` is NULL then the convex hull will be stored in the same storage as the input sequence - - :type storage: :class:`CvMemStorage` - - - :param orientation: Desired orientation of convex hull: ``CV_CLOCKWISE`` or ``CV_COUNTER_CLOCKWISE`` - - :type orientation: int - - - :param return_points: If non-zero, the points themselves will be stored in the hull instead of indices if ``storage`` is an array, or pointers if ``storage`` is memory storage - - :type return_points: int - - - -The function finds the convex hull of a 2D point set using Sklansky's algorithm. If -``storage`` -is memory storage, the function creates a sequence containing the hull points or pointers to them, depending on -``return_points`` -value and returns the sequence on output. If -``storage`` -is a CvMat, the function returns NULL. - - -.. index:: ConvexityDefects - -.. _ConvexityDefects: - -ConvexityDefects ----------------- - - - - -.. function:: ConvexityDefects(contour,convexhull,storage)-> convexity_defects - - Finds the convexity defects of a contour. - - - - - - - :param contour: Input contour - - :type contour: :class:`CvArr` or :class:`CvSeq` - - - :param convexhull: Convex hull obtained using :ref:`ConvexHull2` that should contain pointers or indices to the contour points, not the hull points themselves (the ``return_points`` parameter in :ref:`ConvexHull2` should be 0) - - :type convexhull: :class:`CvSeq` - - - :param storage: Container for the output sequence of convexity defects. If it is NULL, the contour or hull (in that order) storage is used - - :type storage: :class:`CvMemStorage` - - - -The function finds all convexity defects of the input contour and returns a sequence of the CvConvexityDefect structures. - - -.. index:: CreateContourTree - -.. _CreateContourTree: - -CreateContourTree ------------------ - - - - -.. function:: CreateContourTree(contour,storage,threshold)-> contour_tree - - Creates a hierarchical representation of a contour. - - - - - - - :param contour: Input contour - - - :param storage: Container for output tree - - - :param threshold: Approximation accuracy - - - -The function creates a binary tree representation for the input -``contour`` -and returns the pointer to its root. If the parameter -``threshold`` -is less than or equal to 0, the function creates a full binary tree representation. If the threshold is greater than 0, the function creates a representation with the precision -``threshold`` -: if the vertices with the interceptive area of its base line are less than -``threshold`` -, the tree should not be built any further. The function returns the created tree. - - -.. index:: FindContours - -.. _FindContours: - -FindContours ------------- - - - - -.. function:: FindContours(image, storage, mode=CV_RETR_LIST, method=CV_CHAIN_APPROX_SIMPLE, offset=(0,0)) -> cvseq - - Finds the contours in a binary image. - - - - - - - :param image: The source, an 8-bit single channel image. Non-zero pixels are treated as 1's, zero pixels remain 0's - the image is treated as ``binary`` . To get such a binary image from grayscale, one may use :ref:`Threshold` , :ref:`AdaptiveThreshold` or :ref:`Canny` . The function modifies the source image's content - - :type image: :class:`CvArr` - - - :param storage: Container of the retrieved contours - - :type storage: :class:`CvMemStorage` - - - :param mode: Retrieval mode - - - * **CV_RETR_EXTERNAL** retrives only the extreme outer contours - - - * **CV_RETR_LIST** retrieves all of the contours and puts them in the list - - - * **CV_RETR_CCOMP** retrieves all of the contours and organizes them into a two-level hierarchy: on the top level are the external boundaries of the components, on the second level are the boundaries of the holes - - - * **CV_RETR_TREE** retrieves all of the contours and reconstructs the full hierarchy of nested contours - - - - :type mode: int - - - :param method: Approximation method (for all the modes, except ``CV_LINK_RUNS`` , which uses built-in approximation) - - - * **CV_CHAIN_CODE** outputs contours in the Freeman chain code. All other methods output polygons (sequences of vertices) - - - * **CV_CHAIN_APPROX_NONE** translates all of the points from the chain code into points - - - * **CV_CHAIN_APPROX_SIMPLE** compresses horizontal, vertical, and diagonal segments and leaves only their end points - - - * **CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS** applies one of the flavors of the Teh-Chin chain approximation algorithm. - - - * **CV_LINK_RUNS** uses a completely different contour retrieval algorithm by linking horizontal segments of 1's. Only the ``CV_RETR_LIST`` retrieval mode can be used with this method. - - - - :type method: int - - - :param offset: Offset, by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context - - :type offset: :class:`CvPoint` - - - -The function retrieves contours from the binary image using the algorithm -Suzuki85 -. The contours are a useful tool for shape analysis and -object detection and recognition. - -The function retrieves contours from the -binary image and returns the number of retrieved contours. The -pointer -``first_contour`` -is filled by the function. It will -contain a pointer to the first outermost contour or -``NULL`` -if no -contours are detected (if the image is completely black). Other -contours may be reached from -``first_contour`` -using the -``h_next`` -and -``v_next`` -links. The sample in the -:ref:`DrawContours` -discussion shows how to use contours for -connected component detection. Contours can be also used for shape -analysis and object recognition - see -``squares.py`` -in the OpenCV sample directory. - -**Note:** -the source -``image`` -is modified by this function. - - -.. index:: FitEllipse2 - -.. _FitEllipse2: - -FitEllipse2 ------------ - - - - -.. function:: FitEllipse2(points)-> Box2D - - Fits an ellipse around a set of 2D points. - - - - - - - :param points: Sequence or array of points - - :type points: :class:`CvArr` - - - -The function calculates the ellipse that fits best -(in least-squares sense) around a set of 2D points. The meaning of the -returned structure fields is similar to those in -:ref:`Ellipse` -except -that -``size`` -stores the full lengths of the ellipse axises, -not half-lengths. - - -.. index:: FitLine - -.. _FitLine: - -FitLine -------- - - - - -.. function:: FitLine(points, dist_type, param, reps, aeps) -> line - - Fits a line to a 2D or 3D point set. - - - - - - - :param points: Sequence or array of 2D or 3D points with 32-bit integer or floating-point coordinates - - :type points: :class:`CvArr` - - - :param dist_type: The distance used for fitting (see the discussion) - - :type dist_type: int - - - :param param: Numerical parameter ( ``C`` ) for some types of distances, if 0 then some optimal value is chosen - - :type param: float - - - :param reps: Sufficient accuracy for the radius (distance between the coordinate origin and the line). 0.01 is a good default value. - - :type reps: float - - - :param aeps: Sufficient accuracy for the angle. 0.01 is a good default value. - - :type aeps: float - - - :param line: The output line parameters. In the case of a 2d fitting, - it is a tuple of 4 floats ``(vx, vy, x0, y0)`` where ``(vx, vy)`` is a normalized vector collinear to the - line and ``(x0, y0)`` is some point on the line. in the case of a - 3D fitting it is a tuple of 6 floats ``(vx, vy, vz, x0, y0, z0)`` - where ``(vx, vy, vz)`` is a normalized vector collinear to the line - and ``(x0, y0, z0)`` is some point on the line - - :type line: object - - - -The function fits a line to a 2D or 3D point set by minimizing -:math:`\sum_i \rho(r_i)` -where -:math:`r_i` -is the distance between the -:math:`i` -th point and the line and -:math:`\rho(r)` -is a distance function, one of: - - - - - -* dist\_type=CV\_DIST\_L2 - - - .. math:: - - \rho (r) = r^2/2 \quad \text{(the simplest and the fastest least-squares method)} - - - - -* dist\_type=CV\_DIST\_L1 - - - .. math:: - - \rho (r) = r - - - - -* dist\_type=CV\_DIST\_L12 - - - .. math:: - - \rho (r) = 2 \cdot ( \sqrt{1 + \frac{r^2}{2}} - 1) - - - - -* dist\_type=CV\_DIST\_FAIR - - - .. math:: - - \rho \left (r \right ) = C^2 \cdot \left ( \frac{r}{C} - \log{\left(1 + \frac{r}{C}\right)} \right ) \quad \text{where} \quad C=1.3998 - - - - -* dist\_type=CV\_DIST\_WELSCH - - - .. math:: - - \rho \left (r \right ) = \frac{C^2}{2} \cdot \left ( 1 - \exp{\left(-\left(\frac{r}{C}\right)^2\right)} \right ) \quad \text{where} \quad C=2.9846 - - - - -* dist\_type=CV\_DIST\_HUBER - - - .. math:: - - \rho (r) = \fork{r^2/2}{if $r < C$}{C \cdot (r-C/2)}{otherwise} \quad \text{where} \quad C=1.345 - - - - - -.. index:: GetCentralMoment - -.. _GetCentralMoment: - -GetCentralMoment ----------------- - - - - -.. function:: GetCentralMoment(moments, x_order, y_order) -> double - - Retrieves the central moment from the moment state structure. - - - - - - - :param moments: Pointer to the moment state structure - - :type moments: :class:`CvMoments` - - - :param x_order: x order of the retrieved moment, :math:`\texttt{x\_order} >= 0` - - :type x_order: int - - - :param y_order: y order of the retrieved moment, :math:`\texttt{y\_order} >= 0` and :math:`\texttt{x\_order} + \texttt{y\_order} <= 3` - - :type y_order: int - - - -The function retrieves the central moment, which in the case of image moments is defined as: - - - -.. math:: - - \mu _{x \_ order, \, y \_ order} = \sum _{x,y} (I(x,y) \cdot (x-x_c)^{x \_ order} \cdot (y-y_c)^{y \_ order}) - - -where -:math:`x_c,y_c` -are the coordinates of the gravity center: - - - -.. math:: - - x_c= \frac{M_{10}}{M_{00}} , y_c= \frac{M_{01}}{M_{00}} - - - -.. index:: GetHuMoments - -.. _GetHuMoments: - -GetHuMoments ------------- - - - - -.. function:: GetHuMoments(moments) -> hu - - Calculates the seven Hu invariants. - - - - - - - :param moments: The input moments, computed with :ref:`Moments` - - :type moments: :class:`CvMoments` - - - :param hu: The output Hu invariants - - :type hu: object - - - -The function calculates the seven Hu invariants, see -http://en.wikipedia.org/wiki/Image_moment -, that are defined as: - - - -.. math:: - - \begin{array}{l} hu_1= \eta _{20}+ \eta _{02} \\ hu_2=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu_3=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu_4=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu_5=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu_6=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu_7=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array} - - -where -:math:`\eta_{ji}` -denote the normalized central moments. - -These values are proved to be invariant to the image scale, rotation, and reflection except the seventh one, whose sign is changed by reflection. Of course, this invariance was proved with the assumption of infinite image resolution. In case of a raster images the computed Hu invariants for the original and transformed images will be a bit different. - - - - -.. doctest:: - - - - >>> import cv - >>> original = cv.LoadImageM("building.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE) - >>> print cv.GetHuMoments(cv.Moments(original)) - (0.0010620951868446141, 1.7962726159653835e-07, 1.4932744974469421e-11, 4.4832441315737963e-12, -1.0819359198251739e-23, -9.5726503811945833e-16, -3.5050592804744648e-23) - >>> flipped = cv.CloneMat(original) - >>> cv.Flip(original, flipped) - >>> print cv.GetHuMoments(cv.Moments(flipped)) - (0.0010620951868446141, 1.796272615965384e-07, 1.4932744974469935e-11, 4.4832441315740249e-12, -1.0819359198259393e-23, -9.572650381193327e-16, 3.5050592804745877e-23) - - -.. - - -.. index:: GetNormalizedCentralMoment - -.. _GetNormalizedCentralMoment: - -GetNormalizedCentralMoment --------------------------- - - - - -.. function:: GetNormalizedCentralMoment(moments, x_order, y_order) -> double - - Retrieves the normalized central moment from the moment state structure. - - - - - - - :param moments: Pointer to the moment state structure - - :type moments: :class:`CvMoments` - - - :param x_order: x order of the retrieved moment, :math:`\texttt{x\_order} >= 0` - - :type x_order: int - - - :param y_order: y order of the retrieved moment, :math:`\texttt{y\_order} >= 0` and :math:`\texttt{x\_order} + \texttt{y\_order} <= 3` - - :type y_order: int - - - -The function retrieves the normalized central moment: - - - -.. math:: - - \eta _{x \_ order, \, y \_ order} = \frac{\mu_{x\_order, \, y\_order}}{M_{00}^{(y\_order+x\_order)/2+1}} - - - -.. index:: GetSpatialMoment - -.. _GetSpatialMoment: - -GetSpatialMoment ----------------- - - - - -.. function:: GetSpatialMoment(moments, x_order, y_order) -> double - - Retrieves the spatial moment from the moment state structure. - - - - - - - :param moments: The moment state, calculated by :ref:`Moments` - - :type moments: :class:`CvMoments` - - - :param x_order: x order of the retrieved moment, :math:`\texttt{x\_order} >= 0` - - :type x_order: int - - - :param y_order: y order of the retrieved moment, :math:`\texttt{y\_order} >= 0` and :math:`\texttt{x\_order} + \texttt{y\_order} <= 3` - - :type y_order: int - - - -The function retrieves the spatial moment, which in the case of image moments is defined as: - - - -.. math:: - - M_{x \_ order, \, y \_ order} = \sum _{x,y} (I(x,y) \cdot x^{x \_ order} \cdot y^{y \_ order}) - - -where -:math:`I(x,y)` -is the intensity of the pixel -:math:`(x, y)` -. - - -.. index:: MatchContourTrees - -.. _MatchContourTrees: - -MatchContourTrees ------------------ - - - - -.. function:: MatchContourTrees(tree1,tree2,method,threshold)-> double - - Compares two contours using their tree representations. - - - - - - - :param tree1: First contour tree - - - :param tree2: Second contour tree - - - :param method: Similarity measure, only ``CV_CONTOUR_TREES_MATCH_I1`` is supported - - - :param threshold: Similarity threshold - - - -The function calculates the value of the matching measure for two contour trees. The similarity measure is calculated level by level from the binary tree roots. If at a certain level the difference between contours becomes less than -``threshold`` -, the reconstruction process is interrupted and the current difference is returned. - - -.. index:: MatchShapes - -.. _MatchShapes: - -MatchShapes ------------ - - - - -.. function:: MatchShapes(object1,object2,method,parameter=0)-> None - - Compares two shapes. - - - - - - - :param object1: First contour or grayscale image - - :type object1: :class:`CvSeq` - - - :param object2: Second contour or grayscale image - - :type object2: :class:`CvSeq` - - - :param method: Comparison method; - ``CV_CONTOUR_MATCH_I1`` , - ``CV_CONTOURS_MATCH_I2`` - or - ``CV_CONTOURS_MATCH_I3`` - - :type method: int - - - :param parameter: Method-specific parameter (is not used now) - - :type parameter: float - - - -The function compares two shapes. The 3 implemented methods all use Hu moments (see -:ref:`GetHuMoments` -) ( -:math:`A` -is -``object1`` -, -:math:`B` -is -``object2`` -): - - - - - -* method=CV\_CONTOUR\_MATCH\_I1 - - - .. math:: - - I_1(A,B) = \sum _{i=1...7} \left | \frac{1}{m^A_i} - \frac{1}{m^B_i} \right | - - - - -* method=CV\_CONTOUR\_MATCH\_I2 - - - .. math:: - - I_2(A,B) = \sum _{i=1...7} \left | m^A_i - m^B_i \right | - - - - -* method=CV\_CONTOUR\_MATCH\_I3 - - - .. math:: - - I_3(A,B) = \sum _{i=1...7} \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| } - - - - -where - - - -.. math:: - - \begin{array}{l} m^A_i = sign(h^A_i) \cdot \log{h^A_i} m^B_i = sign(h^B_i) \cdot \log{h^B_i} \end{array} - - -and -:math:`h^A_i, h^B_i` -are the Hu moments of -:math:`A` -and -:math:`B` -respectively. - - - -.. index:: MinAreaRect2 - -.. _MinAreaRect2: - -MinAreaRect2 ------------- - - - - -.. function:: MinAreaRect2(points,storage=NULL)-> CvBox2D - - Finds the circumscribed rectangle of minimal area for a given 2D point set. - - - - - - - :param points: Sequence or array of points - - :type points: :class:`CvArr` or :class:`CvSeq` - - - :param storage: Optional temporary memory storage - - :type storage: :class:`CvMemStorage` - - - -The function finds a circumscribed rectangle of the minimal area for a 2D point set by building a convex hull for the set and applying the rotating calipers technique to the hull. - -Picture. Minimal-area bounding rectangle for contour - - - -.. image:: ../pics/minareabox.png - - - - -.. index:: MinEnclosingCircle - -.. _MinEnclosingCircle: - -MinEnclosingCircle ------------------- - - - - -.. function:: MinEnclosingCircle(points)-> (int,center,radius) - - Finds the circumscribed circle of minimal area for a given 2D point set. - - - - - - - :param points: Sequence or array of 2D points - - :type points: :class:`CvArr` or :class:`CvSeq` - - - :param center: Output parameter; the center of the enclosing circle - - :type center: :class:`CvPoint2D32f` - - - :param radius: Output parameter; the radius of the enclosing circle - - :type radius: float - - - -The function finds the minimal circumscribed -circle for a 2D point set using an iterative algorithm. It returns nonzero -if the resultant circle contains all the input points and zero otherwise -(i.e. the algorithm failed). - - -.. index:: Moments - -.. _Moments: - -Moments -------- - - - - -.. function:: Moments(arr, binary = 0) -> moments - - Calculates all of the moments up to the third order of a polygon or rasterized shape. - - - - - - - :param arr: Image (1-channel or 3-channel with COI set) or polygon (CvSeq of points or a vector of points) - - :type arr: :class:`CvArr` or :class:`CvSeq` - - - :param moments: Pointer to returned moment's state structure - - :type moments: :class:`CvMoments` - - - :param binary: (For images only) If the flag is non-zero, all of the zero pixel values are treated as zeroes, and all of the others are treated as 1's - - :type binary: int - - - -The function calculates spatial and central moments up to the third order and writes them to -``moments`` -. The moments may then be used then to calculate the gravity center of the shape, its area, main axises and various shape characeteristics including 7 Hu invariants. - - -.. index:: PointPolygonTest - -.. _PointPolygonTest: - -PointPolygonTest ----------------- - - - - -.. function:: PointPolygonTest(contour,pt,measure_dist)-> double - - Point in contour test. - - - - - - - :param contour: Input contour - - :type contour: :class:`CvArr` or :class:`CvSeq` - - - :param pt: The point tested against the contour - - :type pt: :class:`CvPoint2D32f` - - - :param measure_dist: If it is non-zero, the function estimates the distance from the point to the nearest contour edge - - :type measure_dist: int - - - -The function determines whether the -point is inside a contour, outside, or lies on an edge (or coinsides -with a vertex). It returns positive, negative or zero value, -correspondingly. When -:math:`\texttt{measure\_dist} =0` -, the return value -is +1, -1 and 0, respectively. When -:math:`\texttt{measure\_dist} \ne 0` -, -it is a signed distance between the point and the nearest contour -edge. - -Here is the sample output of the function, where each image pixel is tested against the contour. - - - -.. image:: ../pics/pointpolygon.png - - - diff --git a/doc/opencv1/py/introduction.rst b/doc/opencv1/py/introduction.rst deleted file mode 100644 index bda7de5014..0000000000 --- a/doc/opencv1/py/introduction.rst +++ /dev/null @@ -1,37 +0,0 @@ -************ -Introduction -************ - - -Starting with release 2.0, OpenCV has a new Python interface. This replaces the previous -`SWIG-based Python interface `_ -. - -Some highlights of the new bindings: - - - - - -* single import of all of OpenCV using ``import cv`` - - -* OpenCV functions no longer have the "cv" prefix - - -* simple types like CvRect and CvScalar use Python tuples - - -* sharing of Image storage, so image transport between OpenCV and other systems (e.g. numpy and ROS) is very efficient - - -* complete documentation for the Python functions - - -This cookbook section contains a few illustrative examples of OpenCV Python code. - - -.. toctree:: - :maxdepth: 2 - - cookbook diff --git a/doc/opencv1/py/objdetect.rst b/doc/opencv1/py/objdetect.rst deleted file mode 100644 index 4c2b983f15..0000000000 --- a/doc/opencv1/py/objdetect.rst +++ /dev/null @@ -1,10 +0,0 @@ -*************************** -objdetect. Object Detection -*************************** - - - -.. toctree:: - :maxdepth: 2 - - objdetect_cascade_classification diff --git a/doc/opencv1/py/objdetect_cascade_classification.rst b/doc/opencv1/py/objdetect_cascade_classification.rst deleted file mode 100644 index 7e2f5c5503..0000000000 --- a/doc/opencv1/py/objdetect_cascade_classification.rst +++ /dev/null @@ -1,180 +0,0 @@ -Cascade Classification -====================== - -.. highlight:: python - - - -Haar Feature-based Cascade Classifier for Object Detection ----------------------------------------------------------- - - -The object detector described below has been initially proposed by Paul Viola -:ref:`Viola01` -and improved by Rainer Lienhart -:ref:`Lienhart02` -. First, a classifier (namely a -*cascade of boosted classifiers working with haar-like features* -) is trained with a few hundred sample views of a particular object (i.e., a face or a car), called positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary images of the same size. - -After a classifier is trained, it can be applied to a region of interest -(of the same size as used during the training) in an input image. The -classifier outputs a "1" if the region is likely to show the object -(i.e., face/car), and "0" otherwise. To search for the object in the -whole image one can move the search window across the image and check -every location using the classifier. The classifier is designed so that -it can be easily "resized" in order to be able to find the objects of -interest at different sizes, which is more efficient than resizing the -image itself. So, to find an object of an unknown size in the image the -scan procedure should be done several times at different scales. - -The word "cascade" in the classifier name means that the resultant -classifier consists of several simpler classifiers ( -*stages* -) that -are applied subsequently to a region of interest until at some stage the -candidate is rejected or all the stages are passed. The word "boosted" -means that the classifiers at every stage of the cascade are complex -themselves and they are built out of basic classifiers using one of four -different -``boosting`` -techniques (weighted voting). Currently -Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are -supported. The basic classifiers are decision-tree classifiers with at -least 2 leaves. Haar-like features are the input to the basic classifers, -and are calculated as described below. The current algorithm uses the -following Haar-like features: - - - -.. image:: ../pics/haarfeatures.png - - - -The feature used in a particular classifier is specified by its shape (1a, 2b etc.), position within the region of interest and the scale (this scale is not the same as the scale used at the detection stage, though these two scales are multiplied). For example, in the case of the third line feature (2c) the response is calculated as the difference between the sum of image pixels under the rectangle covering the whole feature (including the two white stripes and the black stripe in the middle) and the sum of the image pixels under the black stripe multiplied by 3 in order to compensate for the differences in the size of areas. The sums of pixel values over a rectangular regions are calculated rapidly using integral images (see below and the -:ref:`Integral` -description). - -A simple demonstration of face detection, which draws a rectangle around each detected face: - - - - -:: - - - - - hc = cv.Load("haarcascade_frontalface_default.xml") - img = cv.LoadImage("faces.jpg", 0) - faces = cv.HaarDetectObjects(img, hc, cv.CreateMemStorage()) - for (x,y,w,h),n in faces: - cv.Rectangle(img, (x,y), (x+w,y+h), 255) - cv.SaveImage("faces_detected.jpg", img) - - - -.. - - -.. index:: HaarDetectObjects - -.. _HaarDetectObjects: - -HaarDetectObjects ------------------ - - - - -.. function:: HaarDetectObjects(image,cascade,storage,scaleFactor=1.1,minNeighbors=3,flags=0,minSize=(0,0))-> detected_objects - - Detects objects in the image. - - - - - - - :param image: Image to detect objects in - - :type image: :class:`CvArr` - - - :param cascade: Haar classifier cascade in internal representation - - :type cascade: :class:`CvHaarClassifierCascade` - - - :param storage: Memory storage to store the resultant sequence of the object candidate rectangles - - :type storage: :class:`CvMemStorage` - - - :param scaleFactor: The factor by which the search window is scaled between the subsequent scans, 1.1 means increasing window by 10 % - - - :param minNeighbors: Minimum number (minus 1) of neighbor rectangles that makes up an object. All the groups of a smaller number of rectangles than ``min_neighbors`` -1 are rejected. If ``minNeighbors`` is 0, the function does not any grouping at all and returns all the detected candidate rectangles, which may be useful if the user wants to apply a customized grouping procedure - - - :param flags: Mode of operation. Currently the only flag that may be specified is ``CV_HAAR_DO_CANNY_PRUNING`` . If it is set, the function uses Canny edge detector to reject some image regions that contain too few or too much edges and thus can not contain the searched object. The particular threshold values are tuned for face detection and in this case the pruning speeds up the processing - - :type flags: int - - - :param minSize: Minimum window size. By default, it is set to the size of samples the classifier has been trained on ( :math:`\sim 20\times 20` for face detection) - - - :param maxSize: Maximum window size to use. By default, it is set to the size of the image. - - - -The function finds rectangular regions in the given image that are likely to contain objects the cascade has been trained for and returns those regions as a sequence of rectangles. The function scans the image several times at different scales (see -:ref:`SetImagesForHaarClassifierCascade` -). Each time it considers overlapping regions in the image and applies the classifiers to the regions using -:ref:`RunHaarClassifierCascade` -. It may also apply some heuristics to reduce number of analyzed regions, such as Canny prunning. After it has proceeded and collected the candidate rectangles (regions that passed the classifier cascade), it groups them and returns a sequence of average rectangles for each large enough group. The default parameters ( -``scale_factor`` -=1.1, -``min_neighbors`` -=3, -``flags`` -=0) are tuned for accurate yet slow object detection. For a faster operation on real video images the settings are: -``scale_factor`` -=1.2, -``min_neighbors`` -=2, -``flags`` -= -``CV_HAAR_DO_CANNY_PRUNING`` -, -``min_size`` -= -*minimum possible face size* -(for example, -:math:`\sim` -1/4 to 1/16 of the image area in the case of video conferencing). - -The function returns a list of tuples, -``(rect, neighbors)`` -, where rect is a -:ref:`CvRect` -specifying the object's extents -and neighbors is a number of neighbors. - - - - -.. doctest:: - - - - >>> import cv - >>> image = cv.LoadImageM("lena.jpg", cv.CV_LOAD_IMAGE_GRAYSCALE) - >>> cascade = cv.Load("../../data/haarcascades/haarcascade_frontalface_alt.xml") - >>> print cv.HaarDetectObjects(image, cascade, cv.CreateMemStorage(0), 1.2, 2, 0, (20, 20)) - [((217, 203, 169, 169), 24)] - - -.. - diff --git a/doc/opencv1/py/py_index.rst b/doc/opencv1/py/py_index.rst deleted file mode 100644 index d6117ed8f2..0000000000 --- a/doc/opencv1/py/py_index.rst +++ /dev/null @@ -1,17 +0,0 @@ -############################### -OpenCV 1.x Python API Reference -############################### - -.. highlight:: python - -.. toctree:: - :maxdepth: 2 - - introduction - core - imgproc - features2d - objdetect - video - highgui - calib3d diff --git a/doc/opencv1/py/video.rst b/doc/opencv1/py/video.rst deleted file mode 100644 index 5c1c79baa4..0000000000 --- a/doc/opencv1/py/video.rst +++ /dev/null @@ -1,10 +0,0 @@ -********************* -video. Video Analysis -********************* - - - -.. toctree:: - :maxdepth: 2 - - video_motion_analysis_and_object_tracking diff --git a/doc/opencv1/py/video_motion_analysis_and_object_tracking.rst b/doc/opencv1/py/video_motion_analysis_and_object_tracking.rst deleted file mode 100644 index 1fcffe154d..0000000000 --- a/doc/opencv1/py/video_motion_analysis_and_object_tracking.rst +++ /dev/null @@ -1,1116 +0,0 @@ -Motion Analysis and Object Tracking -=================================== - -.. highlight:: python - - - -.. index:: CalcGlobalOrientation - -.. _CalcGlobalOrientation: - -CalcGlobalOrientation ---------------------- - - - - -.. function:: CalcGlobalOrientation(orientation,mask,mhi,timestamp,duration)-> float - - Calculates the global motion orientation of some selected region. - - - - - - - :param orientation: Motion gradient orientation image; calculated by the function :ref:`CalcMotionGradient` - - :type orientation: :class:`CvArr` - - - :param mask: Mask image. It may be a conjunction of a valid gradient mask, obtained with :ref:`CalcMotionGradient` and the mask of the region, whose direction needs to be calculated - - :type mask: :class:`CvArr` - - - :param mhi: Motion history image - - :type mhi: :class:`CvArr` - - - :param timestamp: Current time in milliseconds or other units, it is better to store time passed to :ref:`UpdateMotionHistory` before and reuse it here, because running :ref:`UpdateMotionHistory` and :ref:`CalcMotionGradient` on large images may take some time - - :type timestamp: float - - - :param duration: Maximal duration of motion track in milliseconds, the same as :ref:`UpdateMotionHistory` - - :type duration: float - - - -The function calculates the general -motion direction in the selected region and returns the angle between -0 degrees and 360 degrees . At first the function builds the orientation histogram -and finds the basic orientation as a coordinate of the histogram -maximum. After that the function calculates the shift relative to the -basic orientation as a weighted sum of all of the orientation vectors: the more -recent the motion, the greater the weight. The resultant angle is -a circular sum of the basic orientation and the shift. - - -.. index:: CalcMotionGradient - -.. _CalcMotionGradient: - -CalcMotionGradient ------------------- - - - - -.. function:: CalcMotionGradient(mhi,mask,orientation,delta1,delta2,apertureSize=3)-> None - - Calculates the gradient orientation of a motion history image. - - - - - - - :param mhi: Motion history image - - :type mhi: :class:`CvArr` - - - :param mask: Mask image; marks pixels where the motion gradient data is correct; output parameter - - :type mask: :class:`CvArr` - - - :param orientation: Motion gradient orientation image; contains angles from 0 to ~360 degrees - - :type orientation: :class:`CvArr` - - - :param delta1: See below - - :type delta1: float - - - :param delta2: See below - - :type delta2: float - - - :param apertureSize: Aperture size of derivative operators used by the function: CV _ SCHARR, 1, 3, 5 or 7 (see :ref:`Sobel` ) - - :type apertureSize: int - - - -The function calculates the derivatives -:math:`Dx` -and -:math:`Dy` -of -``mhi`` -and then calculates gradient orientation as: - - - -.. math:: - - \texttt{orientation} (x,y)= \arctan{\frac{Dy(x,y)}{Dx(x,y)}} - - -where both -:math:`Dx(x,y)` -and -:math:`Dy(x,y)` -signs are taken into account (as in the -:ref:`CartToPolar` -function). After that -``mask`` -is filled to indicate where the orientation is valid (see the -``delta1`` -and -``delta2`` -description). - -The function finds the minimum ( -:math:`m(x,y)` -) and maximum ( -:math:`M(x,y)` -) mhi values over each pixel -:math:`(x,y)` -neighborhood and assumes the gradient is valid only if - - -.. math:: - - \min ( \texttt{delta1} , \texttt{delta2} ) \le M(x,y)-m(x,y) \le \max ( \texttt{delta1} , \texttt{delta2} ). - - - -.. index:: CalcOpticalFlowBM - -.. _CalcOpticalFlowBM: - -CalcOpticalFlowBM ------------------ - - - - -.. function:: CalcOpticalFlowBM(prev,curr,blockSize,shiftSize,max_range,usePrevious,velx,vely)-> None - - Calculates the optical flow for two images by using the block matching method. - - - - - - - :param prev: First image, 8-bit, single-channel - - :type prev: :class:`CvArr` - - - :param curr: Second image, 8-bit, single-channel - - :type curr: :class:`CvArr` - - - :param blockSize: Size of basic blocks that are compared - - :type blockSize: :class:`CvSize` - - - :param shiftSize: Block coordinate increments - - :type shiftSize: :class:`CvSize` - - - :param max_range: Size of the scanned neighborhood in pixels around the block - - :type max_range: :class:`CvSize` - - - :param usePrevious: Uses the previous (input) velocity field - - :type usePrevious: int - - - :param velx: Horizontal component of the optical flow of - - .. math:: - - \left \lfloor \frac{\texttt{prev->width} - \texttt{blockSize.width}}{\texttt{shiftSize.width}} \right \rfloor \times \left \lfloor \frac{\texttt{prev->height} - \texttt{blockSize.height}}{\texttt{shiftSize.height}} \right \rfloor - - size, 32-bit floating-point, single-channel - - :type velx: :class:`CvArr` - - - :param vely: Vertical component of the optical flow of the same size ``velx`` , 32-bit floating-point, single-channel - - :type vely: :class:`CvArr` - - - -The function calculates the optical -flow for overlapped blocks -:math:`\texttt{blockSize.width} \times \texttt{blockSize.height}` -pixels each, thus the velocity -fields are smaller than the original images. For every block in -``prev`` -the functions tries to find a similar block in -``curr`` -in some neighborhood of the original block or shifted by (velx(x0,y0),vely(x0,y0)) block as has been calculated by previous -function call (if -``usePrevious=1`` -) - - -.. index:: CalcOpticalFlowHS - -.. _CalcOpticalFlowHS: - -CalcOpticalFlowHS ------------------ - - - - -.. function:: CalcOpticalFlowHS(prev,curr,usePrevious,velx,vely,lambda,criteria)-> None - - Calculates the optical flow for two images. - - - - - - - :param prev: First image, 8-bit, single-channel - - :type prev: :class:`CvArr` - - - :param curr: Second image, 8-bit, single-channel - - :type curr: :class:`CvArr` - - - :param usePrevious: Uses the previous (input) velocity field - - :type usePrevious: int - - - :param velx: Horizontal component of the optical flow of the same size as input images, 32-bit floating-point, single-channel - - :type velx: :class:`CvArr` - - - :param vely: Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel - - :type vely: :class:`CvArr` - - - :param lambda: Lagrangian multiplier - - :type lambda: float - - - :param criteria: Criteria of termination of velocity computing - - :type criteria: :class:`CvTermCriteria` - - - -The function computes the flow for every pixel of the first input image using the Horn and Schunck algorithm -Horn81 -. - - -.. index:: CalcOpticalFlowLK - -.. _CalcOpticalFlowLK: - -CalcOpticalFlowLK ------------------ - - - - -.. function:: CalcOpticalFlowLK(prev,curr,winSize,velx,vely)-> None - - Calculates the optical flow for two images. - - - - - - - :param prev: First image, 8-bit, single-channel - - :type prev: :class:`CvArr` - - - :param curr: Second image, 8-bit, single-channel - - :type curr: :class:`CvArr` - - - :param winSize: Size of the averaging window used for grouping pixels - - :type winSize: :class:`CvSize` - - - :param velx: Horizontal component of the optical flow of the same size as input images, 32-bit floating-point, single-channel - - :type velx: :class:`CvArr` - - - :param vely: Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel - - :type vely: :class:`CvArr` - - - -The function computes the flow for every pixel of the first input image using the Lucas and Kanade algorithm -Lucas81 -. - - -.. index:: CalcOpticalFlowPyrLK - -.. _CalcOpticalFlowPyrLK: - -CalcOpticalFlowPyrLK --------------------- - - - - -.. function:: CalcOpticalFlowPyrLK( prev, curr, prevPyr, currPyr, prevFeatures, winSize, level, criteria, flags, guesses = None) -> (currFeatures, status, track_error) - - Calculates the optical flow for a sparse feature set using the iterative Lucas-Kanade method with pyramids. - - - - - - - :param prev: First frame, at time ``t`` - - :type prev: :class:`CvArr` - - - :param curr: Second frame, at time ``t + dt`` - - :type curr: :class:`CvArr` - - - :param prevPyr: Buffer for the pyramid for the first frame. If the pointer is not ``NULL`` , the buffer must have a sufficient size to store the pyramid from level ``1`` to level ``level`` ; the total size of ``(image_width+8)*image_height/3`` bytes is sufficient - - :type prevPyr: :class:`CvArr` - - - :param currPyr: Similar to ``prevPyr`` , used for the second frame - - :type currPyr: :class:`CvArr` - - - :param prevFeatures: Array of points for which the flow needs to be found - - :type prevFeatures: :class:`CvPoint2D32f` - - - :param currFeatures: Array of 2D points containing the calculated new positions of the input features in the second image - - :type currFeatures: :class:`CvPoint2D32f` - - - :param winSize: Size of the search window of each pyramid level - - :type winSize: :class:`CvSize` - - - :param level: Maximal pyramid level number. If ``0`` , pyramids are not used (single level), if ``1`` , two levels are used, etc - - :type level: int - - - :param status: Array. Every element of the array is set to ``1`` if the flow for the corresponding feature has been found, ``0`` otherwise - - :type status: str - - - :param track_error: Array of double numbers containing the difference between patches around the original and moved points. Optional parameter; can be ``NULL`` - - :type track_error: float - - - :param criteria: Specifies when the iteration process of finding the flow for each point on each pyramid level should be stopped - - :type criteria: :class:`CvTermCriteria` - - - :param flags: Miscellaneous flags: - - - * **CV_LKFLOWPyr_A_READY** pyramid for the first frame is precalculated before the call - - - * **CV_LKFLOWPyr_B_READY** pyramid for the second frame is precalculated before the call - - - - - :type flags: int - - - :param guesses: optional array of estimated coordinates of features in second frame, with same length as ``prevFeatures`` - - :type guesses: :class:`CvPoint2D32f` - - - -The function implements the sparse iterative version of the Lucas-Kanade optical flow in pyramids -Bouguet00 -. It calculates the coordinates of the feature points on the current video -frame given their coordinates on the previous frame. The function finds -the coordinates with sub-pixel accuracy. - -Both parameters -``prevPyr`` -and -``currPyr`` -comply with the -following rules: if the image pointer is 0, the function allocates the -buffer internally, calculates the pyramid, and releases the buffer after -processing. Otherwise, the function calculates the pyramid and stores -it in the buffer unless the flag -``CV_LKFLOWPyr_A[B]_READY`` -is set. The image should be large enough to fit the Gaussian pyramid -data. After the function call both pyramids are calculated and the -readiness flag for the corresponding image can be set in the next call -(i.e., typically, for all the image pairs except the very first one -``CV_LKFLOWPyr_A_READY`` -is set). - - - -.. index:: CamShift - -.. _CamShift: - -CamShift --------- - - - - -.. function:: CamShift(prob_image,window,criteria)-> (int, comp, box) - - Finds the object center, size, and orientation. - - - - - - - :param prob_image: Back projection of object histogram (see :ref:`CalcBackProject` ) - - :type prob_image: :class:`CvArr` - - - :param window: Initial search window - - :type window: :class:`CvRect` - - - :param criteria: Criteria applied to determine when the window search should be finished - - :type criteria: :class:`CvTermCriteria` - - - :param comp: Resultant structure that contains the converged search window coordinates ( ``comp->rect`` field) and the sum of all of the pixels inside the window ( ``comp->area`` field) - - :type comp: :class:`CvConnectedComp` - - - :param box: Circumscribed box for the object. - - :type box: :class:`CvBox2D` - - - -The function implements the CAMSHIFT object tracking algrorithm -Bradski98 -. -First, it finds an object center using -:ref:`MeanShift` -and, after that, calculates the object size and orientation. The function returns number of iterations made within -:ref:`MeanShift` -. - -The -``CamShiftTracker`` -class declared in cv.hpp implements the color object tracker that uses the function. - - -.. index:: CvKalman - -.. _CvKalman: - -CvKalman --------- - - - -.. class:: CvKalman - - - -Kalman filter state. - - - - - - .. attribute:: MP - - - - number of measurement vector dimensions - - - - .. attribute:: DP - - - - number of state vector dimensions - - - - .. attribute:: CP - - - - number of control vector dimensions - - - - .. attribute:: state_pre - - - - predicted state (x'(k)): x(k)=A*x(k-1)+B*u(k) - - - - .. attribute:: state_post - - - - corrected state (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) - - - - .. attribute:: transition_matrix - - - - state transition matrix (A) - - - - .. attribute:: control_matrix - - - - control matrix (B) (it is not used if there is no control) - - - - .. attribute:: measurement_matrix - - - - measurement matrix (H) - - - - .. attribute:: process_noise_cov - - - - process noise covariance matrix (Q) - - - - .. attribute:: measurement_noise_cov - - - - measurement noise covariance matrix (R) - - - - .. attribute:: error_cov_pre - - - - priori error estimate covariance matrix (P'(k)): P'(k)=A*P(k-1)*At + Q - - - - .. attribute:: gain - - - - Kalman gain matrix (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R) - - - - .. attribute:: error_cov_post - - - - posteriori error estimate covariance matrix (P(k)): P(k)=(I-K(k)*H)*P'(k) - - - -The structure -``CvKalman`` -is used to keep the Kalman filter -state. It is created by the -:ref:`CreateKalman` -function, updated -by the -:ref:`KalmanPredict` -and -:ref:`KalmanCorrect` -functions -. Normally, the -structure is used for the standard Kalman filter (notation and the -formulas below are borrowed from the excellent Kalman tutorial -Welch95 -) - - - -.. math:: - - \begin{array}{l} x_k=A \cdot x_{k-1}+B \cdot u_k+w_k \\ z_k=H \cdot x_k+v_k \end{array} - - -where: - - - -.. math:: - - \begin{array}{l l} x_k \; (x_{k-1})& \text{state of the system at the moment \emph{k} (\emph{k-1})} \\ z_k & \text{measurement of the system state at the moment \emph{k}} \\ u_k & \text{external control applied at the moment \emph{k}} \end{array} - - -:math:`w_k` -and -:math:`v_k` -are normally-distributed process and measurement noise, respectively: - - - -.. math:: - - \begin{array}{l} p(w) \sim N(0,Q) \\ p(v) \sim N(0,R) \end{array} - - -that is, - -:math:`Q` -process noise covariance matrix, constant or variable, - -:math:`R` -measurement noise covariance matrix, constant or variable - -In the case of the standard Kalman filter, all of the matrices: A, B, H, Q and R are initialized once after the -:ref:`CvKalman` -structure is allocated via -:ref:`CreateKalman` -. However, the same structure and the same functions may be used to simulate the extended Kalman filter by linearizing the extended Kalman filter equation in the current system state neighborhood, in this case A, B, H (and, probably, Q and R) should be updated on every step. - - -.. index:: CreateKalman - -.. _CreateKalman: - -CreateKalman ------------- - - - - -.. function:: CreateKalman(dynam_params, measure_params, control_params=0) -> CvKalman - - Allocates the Kalman filter structure. - - - - - - - :param dynam_params: dimensionality of the state vector - - :type dynam_params: int - - - :param measure_params: dimensionality of the measurement vector - - :type measure_params: int - - - :param control_params: dimensionality of the control vector - - :type control_params: int - - - -The function allocates -:ref:`CvKalman` -and all its matrices and initializes them somehow. - - - -.. index:: KalmanCorrect - -.. _KalmanCorrect: - -KalmanCorrect -------------- - - - - -.. function:: KalmanCorrect(kalman, measurement) -> cvmat - - Adjusts the model state. - - - - - - - :param kalman: Kalman filter object returned by :ref:`CreateKalman` - - :type kalman: :class:`CvKalman` - - - :param measurement: CvMat containing the measurement vector - - :type measurement: :class:`CvMat` - - - -The function adjusts the stochastic model state on the basis of the given measurement of the model state: - - - -.. math:: - - \begin{array}{l} K_k=P'_k \cdot H^T \cdot (H \cdot P'_k \cdot H^T+R)^{-1} \\ x_k=x'_k+K_k \cdot (z_k-H \cdot x'_k) \\ P_k=(I-K_k \cdot H) \cdot P'_k \end{array} - - -where - - -.. table:: - - =========== =============================================== - :math:`z_k` given measurement ( ``mesurement`` parameter) \ - =========== =============================================== - :math:`K_k` Kalman "gain" matrix. \ - =========== =============================================== - -The function stores the adjusted state at -``kalman->state_post`` -and returns it on output. - - -.. index:: KalmanPredict - -.. _KalmanPredict: - -KalmanPredict -------------- - - - - -.. function:: KalmanPredict(kalman, control=None) -> cvmat - - Estimates the subsequent model state. - - - - - - - :param kalman: Kalman filter object returned by :ref:`CreateKalman` - - :type kalman: :class:`CvKalman` - - - :param control: Control vector :math:`u_k` , should be NULL iff there is no external control ( ``control_params`` =0) - - :type control: :class:`CvMat` - - - -The function estimates the subsequent stochastic model state by its current state and stores it at -``kalman->state_pre`` -: - - - -.. math:: - - \begin{array}{l} x'_k=A x_{k-1} + B u_k \\ P'_k=A P_{k-1} A^T + Q \end{array} - - -where - - -.. table:: - - =============== ==================================================================================================================================================================== - :math:`x'_k` is predicted state ``kalman->state_pre`` , \ - =============== ==================================================================================================================================================================== - :math:`x_{k-1}` is corrected state on the previous step ``kalman->state_post`` (should be initialized somehow in the beginning, zero vector by default), \ - :math:`u_k` is external control ( ``control`` parameter), \ - :math:`P'_k` is priori error covariance matrix ``kalman->error_cov_pre`` \ - :math:`P_{k-1}` is posteriori error covariance matrix on the previous step ``kalman->error_cov_post`` (should be initialized somehow in the beginning, identity matrix by default), - =============== ==================================================================================================================================================================== - -The function returns the estimated state. - - -KalmanUpdateByMeasurement -------------------------- - - -Synonym for -:ref:`KalmanCorrect` - -KalmanUpdateByTime ------------------- - - -Synonym for -:ref:`KalmanPredict` - -.. index:: MeanShift - -.. _MeanShift: - -MeanShift ---------- - - - - -.. function:: MeanShift(prob_image,window,criteria)-> comp - - Finds the object center on back projection. - - - - - - - :param prob_image: Back projection of the object histogram (see :ref:`CalcBackProject` ) - - :type prob_image: :class:`CvArr` - - - :param window: Initial search window - - :type window: :class:`CvRect` - - - :param criteria: Criteria applied to determine when the window search should be finished - - :type criteria: :class:`CvTermCriteria` - - - :param comp: Resultant structure that contains the converged search window coordinates ( ``comp->rect`` field) and the sum of all of the pixels inside the window ( ``comp->area`` field) - - :type comp: :class:`CvConnectedComp` - - - -The function iterates to find the object center -given its back projection and initial position of search window. The -iterations are made until the search window center moves by less than -the given value and/or until the function has done the maximum number -of iterations. The function returns the number of iterations made. - - -.. index:: SegmentMotion - -.. _SegmentMotion: - -SegmentMotion -------------- - - - - -.. function:: SegmentMotion(mhi,seg_mask,storage,timestamp,seg_thresh)-> None - - Segments a whole motion into separate moving parts. - - - - - - - :param mhi: Motion history image - - :type mhi: :class:`CvArr` - - - :param seg_mask: Image where the mask found should be stored, single-channel, 32-bit floating-point - - :type seg_mask: :class:`CvArr` - - - :param storage: Memory storage that will contain a sequence of motion connected components - - :type storage: :class:`CvMemStorage` - - - :param timestamp: Current time in milliseconds or other units - - :type timestamp: float - - - :param seg_thresh: Segmentation threshold; recommended to be equal to the interval between motion history "steps" or greater - - :type seg_thresh: float - - - -The function finds all of the motion segments and -marks them in -``seg_mask`` -with individual values (1,2,...). It -also returns a sequence of -:ref:`CvConnectedComp` -structures, one for each motion component. After that the -motion direction for every component can be calculated with -:ref:`CalcGlobalOrientation` -using the extracted mask of the particular -component -:ref:`Cmp` -. - - -.. index:: SnakeImage - -.. _SnakeImage: - -SnakeImage ----------- - - - - -.. function:: SnakeImage(image,points,alpha,beta,gamma,win,criteria,calc_gradient=1)-> new_points - - Changes the contour position to minimize its energy. - - - - - - - :param image: The source image or external energy field - - :type image: :class:`IplImage` - - - :param points: Contour points (snake) - - :type points: :class:`CvPoints` - - - :param alpha: Weight[s] of continuity energy, single float or - a list of floats, one for each contour point - - :type alpha: sequence of float - - - :param beta: Weight[s] of curvature energy, similar to ``alpha`` - - :type beta: sequence of float - - - :param gamma: Weight[s] of image energy, similar to ``alpha`` - - :type gamma: sequence of float - - - :param win: Size of neighborhood of every point used to search the minimum, both ``win.width`` and ``win.height`` must be odd - - :type win: :class:`CvSize` - - - :param criteria: Termination criteria - - :type criteria: :class:`CvTermCriteria` - - - :param calc_gradient: Gradient flag; if not 0, the function calculates the gradient magnitude for every image pixel and consideres it as the energy field, otherwise the input image itself is considered - - :type calc_gradient: int - - - -The function updates the snake in order to minimize its -total energy that is a sum of internal energy that depends on the contour -shape (the smoother contour is, the smaller internal energy is) and -external energy that depends on the energy field and reaches minimum at -the local energy extremums that correspond to the image edges in the case -of using an image gradient. - -The parameter -``criteria.epsilon`` -is used to define the minimal -number of points that must be moved during any iteration to keep the -iteration process running. - -If at some iteration the number of moved points is less -than -``criteria.epsilon`` -or the function performed -``criteria.max_iter`` -iterations, the function terminates. - -The function returns the updated list of points. - -.. index:: UpdateMotionHistory - -.. _UpdateMotionHistory: - -UpdateMotionHistory -------------------- - - - - -.. function:: UpdateMotionHistory(silhouette,mhi,timestamp,duration)-> None - - Updates the motion history image by a moving silhouette. - - - - - - - :param silhouette: Silhouette mask that has non-zero pixels where the motion occurs - - :type silhouette: :class:`CvArr` - - - :param mhi: Motion history image, that is updated by the function (single-channel, 32-bit floating-point) - - :type mhi: :class:`CvArr` - - - :param timestamp: Current time in milliseconds or other units - - :type timestamp: float - - - :param duration: Maximal duration of the motion track in the same units as ``timestamp`` - - :type duration: float - - - -The function updates the motion history image as following: - - - -.. math:: - - \texttt{mhi} (x,y)= \forkthree{\texttt{timestamp}}{if $\texttt{silhouette}(x,y) \ne 0$}{0}{if $\texttt{silhouette}(x,y) = 0$ and $\texttt{mhi} < (\texttt{timestamp} - \texttt{duration})$}{\texttt{mhi}(x,y)}{otherwise} - - -That is, MHI pixels where motion occurs are set to the current timestamp, while the pixels where motion happened far ago are cleared. - diff --git a/doc/pics/backprojectpatch.png b/doc/pics/backprojectpatch.png deleted file mode 100644 index 11dfb29372b89bc0f902f858ddf16b2c7186f10c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3869 zcmeHKdpwl+8nDtrBwtaONVB2$rU z6!M07e*S)4-CemkxpH!H;e>Ez2~!uXE9&kNk$&E`bsMbX?BXn9vqZx@Q3+in6pC`l zB6Bm5zn=(}qfw%*$|5-l5g{Bl{`cqa3jE(zfP`}?5fhVoVtx1@xTt62LrKxkFmj0_ zJs;NwXr80-M4qZ^Y*r=7v~ECOX%Ypkzm^n|XsCW{wYr(awx8wxM7DFacYgDcRy@7S zeCrhI`Y`w9u;%mHY6pb`=?9aa)3oDawM_<+Tb@U6+jGjD=&cjvRTMwqo>9Y}@NbNb zJ7(J6R{tQPF}46*bgDYPtKa!*{PX7KnfqR*45_#I{7aie)f1z$S(_(MK8)UQt3l#z zo_B>>JZ~n|Wc+o^$C-v0NV_QBYalsrRM2iuuWnXynCJ*r+*q4_GcKO!*8HF}&t|u2 z=ugq!&AV&3a7aCF+~mdv597wBc)fhJ#ejEMyY4Nxi&5^!qTHXz3d^G8)52#)HTqCU zlIf++j^Zy3vlR8=)Xc0r+BIkHmF>*LP2Bg?$t=oT7=002o|!anY~4#Tu)-8+rLc}? zvJEQj^zy9qyQQ*7^B&BOq@y8x<7{>&Cg|zmm%Y+qdUiK{JZqh@;B)e)oNP71j&_Uf zm2x(-k?IMJ`Zc1HWmM~jI|2rLFuT*pv7Vi1#Ztyu(Hl+bCYh|ujg7a5w@}!WGfJAJ9(vfRg-}ys5Y)dPWZW9w7am^WYvM4jtu^$h z>-KR|TlICcGrvSUq63*!nq1us`57ZZ*E?_TpPCyIipi?d-6BT0A+VopL6# zX>HoTW2vp{mb>_Vl!VIrA`_(Rgt26nr`|^j?b!+P=5eo? zV{NidW3v4{Q-?VE8k7mJEBUJZm7GKB8m+TGdUryp$;7zFhNe1+fi|nbxY2c^%^!-( z?*Or$cgb6vdtJ!NYkIgJ6#-%nH9|Woy{Ku(8z5rNhh4?QDrs1t`@3-pwnsu|E5`Mp z@2Dh*pijXpGG*02W^l-cM@=jC9oVZ57vTl)A!u-ds(X~_yun7`mPlqkHb0I{ih<82o#&fLo7#;xm#Iq@Xwn(|byBoubC zggE^TND=s!@Y|a$a1;(sR8UIHQvfL#Y)9U?%m#i?0BlKThOrishS2;$^5bGOzn?pz z1)=pjaj(Qr{8qt;%|)$GVX0Ac1j?s&Xvl5=|cP4Apu! ztGw}~4Vs_??ob6UqJU3(HSXrW$7L|Aeh1~hY&_fF*;Bax{XK3TkZ{wazaRGj|7h|G z^wOAM-2Lc9odaGl16jBk0MmP0glwM@2T#=y8?+*M=j3V7PeiPI3TVU@(100YWFB#`!C}ALcPi zt3V1z0je4lU*_4%oa?&G&nm6RvtSUSTm+M0gaCLOEKFekz4j%8?lLWr8;F2Rt!73O z?OQ0!5|$%ozgAn(=)kUDQgcSK_$v$}F?@~rXWPi7!_2Sz3foR2GBiDRDHb3|6A42S zd}fV=!68RDFCXW9b^K|^f5-fX3G(bh%aR3tQIo;l`6OQ?M{B`}P3cR{Gr1ovkT%BK zs57#d2bVmXITzC|Ea}7+HHCifypE;^cR&hh=U!3zpJaehIBwJQ< zX8l7(J=!+&SX|AeEg*iHLABQK^v8Pd8bj@|jU<{hzbZ^)+yv+YWT5kK5oJex0IOuY zO}qYWVf<%oBt`NuE?B$xvoPL+*6@hj?3#4-3uiwhzK=!SpjP?`zc2Si3pZN}NC+q? zbM+rt9DaA&_KYU@y$eOM+~HAYm|Fi`Zk+1t5&CHH=+is6C_nG6l2s$$eI6i0?}f|^`X{e?#ur73 z%YYP>xdl@7T+#!!{aSEX?t$twm4Yq$l~fD+%#aC%_Sw4zJlE zjo}D;QOHptj=fw+ccH2H!^%cL3WLz%(=k}CRo@ou?y3M8kC#3>S0=3liKFRdgcf{9 zcUP*Q_|1h{HC?{{Da$&ysq^p}xnp)NxLE(KDY2iZEg zg?f(Qy+|X{aPPaMG0qrESFw_Dl{v;CYMANkf034y4`lzwKF#a%v6C6%zwxe%gb1ES zLKK81gpRS#zOOlLC-Wi@$P4id>~`9ClYz&kFjA|KemWqn2w|wC(07}vo>K${fo<^Z zLS;)j9)uEetyf`30narO@XqzhnFFSWe*~t>!8cH}a6hsMfFMhld>Xj0Jc3Se&o;&S zEYBglo#9TVZ&rl&Fb(ecKhPHNR3Ou~gr@!l+FkN1boJM0L39~NPJnx1gLB*D7B_ufh@m8Mx{P%cIJ>T&1@k%E02gKUk{&2aO&&7WN D1_cVe diff --git a/doc/pics/bayer.png b/doc/pics/bayer.png deleted file mode 100644 index 92fe2ddb8b57465a8f430847b7c9882de14cb6a1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19476 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 diff --git a/doc/pics/building.jpg b/doc/pics/building.jpg deleted file mode 100644 index 6056492f2fa97d2e57ed078b54b5afd8b6fbb6cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 79718 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%0D+x)x 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 diff --git a/doc/pics/cornersubpix.png b/doc/pics/cornersubpix.png deleted file mode 100644 index b86febbce320061c4e129a5a5428d701f6265b97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1347 zcmZ{ke>7AH6vyApym%u&o*y+x<4q<;wFe>1dg1 z0RW)m&0+=s0A6!N%R$1I+T0tn(rnp2dp*?4>cXNzswGv82SGd-867z&9aNt=y|Vw$ zaJBA90syejo9VVUZFo{H3y|5u8VcX27E726(A!Csu4wO;_AI~WrEd$Z6ibKW_WK>O z65ix>YfgSn9d_8ox?vMKv`-hNKp65*mX#*VcTklB_jC(0c!mnq*uY)gwz2VuigX0P zK`4NSGXe1brJ*|;MWQnK+OQVkJ@f>nGh!7gWX<(=_h*v;i6`zV3)#L3G15XsIHRwZ zBviP!!F!@;B9?wMXmD#{dsH9P>?KIv9b6cHLD`YM>NUpyp&~iXogGW5i6&iP@oogy z8oz&7@lJ-?KE+=dTQQebCFj0W5<~>-R0(i877Us$1i!f=j7Ez}9kFAeDHJp+9OLf>zcVLFT@7gaLHF#j{H@qran~zqxU~8;?+>s^wKwfPRz;rYRPxBYedCPQ>{~~*L7_X=y^;O242W) zEF&|7b4Wf6s*rqRFf5glZ^p}YhFLJaxlik)DG^%VgxP``3@;alu=bdn1wZE~>NPj6 z;&9*qy|<5u%co#&f3RLC9utrsAhUyn95fu6eZtiSN7+w5^LMpEKMBZH$QISq;sTWd zja)}GIUIETkvs_uLAcdE8{l6ZVQhkOY{eqcr792JZe-xqoe78P MygmGw4UBN?ZwrbyM*si- diff --git a/doc/pics/defects.png b/doc/pics/defects.png deleted file mode 100644 index 2ec45ac0bbebf8ba239aaa49be8107ffb03cc19d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23393 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 Ao&W#< diff --git a/doc/pics/disparity.png b/doc/pics/disparity.png deleted file mode 100644 index b337ac5f25eb3dae3df1a1d5ccc7d9524f3a2ed8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3039 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 diff --git a/doc/pics/em1.png b/doc/pics/em1.png deleted file mode 100644 index 74d1cd86cc7501d925c1bbb9c8fd5f63385a5de8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5725 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 EA4x~GSO5S3 diff --git a/doc/pics/em3.png b/doc/pics/em3.png deleted file mode 100644 index a8c0d5f5dda894824cfc6000a5b2ba726d916cc8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6862 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 B9DD!( diff --git a/doc/pics/em5.png b/doc/pics/em5.png deleted file mode 100644 index 9a73d4865079c80cb9bb138f787c31c5b31c17c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3826 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 diff --git a/doc/pics/em6.png b/doc/pics/em6.png deleted file mode 100644 index 0e88bd0b6d8f8ff9d0dd9ca6078822281fb1bffe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2295 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 diff --git a/doc/pics/em7.png b/doc/pics/em7.png deleted file mode 100644 index 8d2981d9625bc2d8d5f9ee465585a30d5fb4412d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2325 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 Tc1(a00C&LE^i*qAp1%Dbw^p1! diff --git a/doc/pics/errmsg.png b/doc/pics/errmsg.png deleted file mode 100644 index e319ececc1de85b305b687fcb8a555c472c04d1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13120 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 IM6N<$g7HYmhX4Qo diff --git a/doc/pics/integral.png b/doc/pics/integral.png deleted file mode 100644 index 97a69c625fd7215ee2c750a1ba61c7699a6c8b69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85298 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 YBiVb?bxWx{G}K2$K?7DRXCC(d0Pkq{5C8xG diff --git a/doc/pics/inv_logpolar.jpg b/doc/pics/inv_logpolar.jpg deleted file mode 100644 index d76f067d2ad207f5d7a4e3c93c1252967cc362c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 42718 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

  • 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 diff --git a/doc/pics/maxrect.png b/doc/pics/maxrect.png deleted file mode 100644 index bc3ff365c76ec1da67cf00578879c63dc07d4335..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 546 zcmeAS@N?(olHy`uVBq!ia0y~yVB`g|=dv&Z$rxROGeF89z$e7@|Ns9$rizM+xw*Ng zr)P9@bZ&00kdP2i5Gx2@TIdBdY^|q@V@SoVx3d_7njLstCrhh*-@oQ0)6|U@R&JPZ zb>H(9va)Yye>j=OC;V$FDm1uKiIXyWDxX+Yf+LbM=nfkJ+cnX<60& zuKTXVKX+Bon}=!Fx`N&;d^Fj;)b31_$Chn!fjuYMUT0~&efM#a^zY*ua$mk0+MYNr z|8+;^{SCW|<3Am=d$kxSu(~Mt`ND`Z#VX;;>mMBa)#SeXFZc1*nhE?iC)nklJdWyjocBK>e!BIq_SjDw{Z1W~ zTYQC?|5IV-@wBO2He1#o|5(El)c@vJ@{=vkm5PrkPfM0xR3EYb^7oSe6~EXk+3V`G z7HsL4wT=?6d=eT^ZrW`oJYV#6x7iV&!>aL1{9J7>9a`S*nj$bhj)EICHtQu;G5UQjmI=@nnwf8UEAREr^M|8Cb);8Tzt{cwd$CK|`fG=8X>Xp@ z<-+{6tYDMU&!gQoTkd|1`L#=As&nzA{>@9aeko&J`lcr`y0h=1-yIfc{MmKtXWqz| T>3s0)Kahy0tDnm{r-UW|Q^@j% diff --git a/doc/pics/minareabox.png b/doc/pics/minareabox.png deleted file mode 100644 index 7c10da16e6e131f9d71c5626c000c23a76ede228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1395 zcmaKsdrVVT9LK*(*m(E|I#fD4wL^x_L2f3YphGAijH|#}8$bckUGRZ{u!^G0t43EV zD_fPZD-WG?igi#;Dak-(;3LRx7DWVKuqmN}tVDvwiDSQA+`r4d$vG!E`Q@B^Kfmue zhvQdAPxg>`0GJ%JN|h+BI%({3bCKqNS(PsU7sSV@BS{jzBxx523JQveiAhOG$xw@|mpC=eTn^f2VFfiV^4?Px4S zdlCA}Ko*c)LCq=>IqK3=uZ4z0hCy^R)~!QM4h|lKAfToOEiLHm#NZ$#Z$t}-5{U|k zs)$4dgTPpXrDIJ#QjOSdMqwk0+ELaI3&Bo`W>Sg7b&J@1S z5+IfZ$ARa^>DX)#MK~N17derVNK2$6G7(uNIub7#1OIpgWh2r6bu}`sA@?zOk`)mn z5PO<98}Usfh-AA*qC;xCWLN{_zllR5&@H*0Ig^$wA(e_!QYbf<^m;mRg6wuF4kQEP z2bKXB2A+kG1RDo24-Ot=lv9P0&S|MZN3AC6vXVoT^2V@WIdD990fG%S5uyXq#s6*K zO}qR!Fg(Hpur?%#;2g*!$%EWT$_mn+BV7ZTTFKfa8CX8-{8fs+d(Nt)JitSGBp$j6 zvGcpffQddas+H=U_npVPw_gcxi&}Ex<=(Wk+OpoOuLh>M%)9L|^UkufA)^6@it83c zs>Y??pLsI0szdJS?Ayom3E?flmm24+w@xY!E9|KC|E+0fdhpG|TMKfPDaNVKdwh@f z?0dGafjybV6lhJsKb?9w>BYMvQ%{>XO&x~Ene}dtHw`#H!iR`)%DJF<)z4PQiC;Jv(4_EI$s}6N$LX4w>_p~ z>RaUlvU`7i9dWwuj7QYDckXX+b)OMYy6~#^s3CN9;j1b0>oR;U=4{Do+vVnA2v5%S z35zW|@X&I{b8S)Q-8}=B*N!x34Lgr4?_1Usn)cDZzZGIPS%u2}(v zT=TZSwN>fwH-2ZXn=!HGuSNEYyQghD*7F0jQ&+YPPszT!JESJ_byCcZj#ulFuFB6Y z?9@68OQ-g~H#o67Yb2o|;mO<13&xvC-=AqustQt%_Ajj7TQRz!`QtOoO3Sib<_uA| z+vefUBes@^txe6p4_DZG;(`-PN6PD3BCgH$`d7m~!>)fd#}x5TyhuS!zK-kPuj;yITYVmd+(4rKL+c z1=;-!??2%C)Av5lJTvFsbI*C5*ST|N=FW}K)6pO!W+DcGKx9ue9~*!`I8ngyk`NE5 z5ptE#0!}y{1{x}$ieZ**K)`o+r2Pm4s*WZ3XG;Lc_g`olXoEn$JRneDCp!9XA+2!y`%1V|7F2m%8^kRS*e1i{`m!XO|R30a-y#KJAs{Raghhg|XaM%D;ak&yEub@?jlK1ATVN0f z5&}U(AlO^CfCPgod7zBxgAkh#c_7)VNi-tkaNC+AYL1O`oKvxJB z2EigBSTqC+cm+@c#sJU&N&ptn1~>+61Ev96Kxgc2K({hbkT4h;2E*RQ2e<_!Boc;1 z!;sk9Z~+uRBN_=qqhV+)5Iq12(1l@W0Xl&A0T4ih0BXP(02)9E zr~)_u$AE3XG++yR%iL`0 z09=4NKr|37KqbHj02Am9&;eiq0tO-kPy@yQ&_GWB7JvhA4A=%tV{cP*s|_>*GElHU z#sDIL_yD(ng#K@k-SYZhzHb}MZ=F3^}#3*4{eJsH*;E+9n;xqpJ*#e#C zAI84?qE=hsB&6)hotv*T;T!!n7U%a+>b>AB692v6zFD1Wke9FfW|Tbro?cdZ#{A!v zm~L_6w5z{=G1HenuD5H>T~1DYFLV5)X$`RFI^TcXXv$uU&*^#0JU0#PZnwk1HnEJ( zj7WdI@x2ogT%WNYdjj9UiyG;?%&$rHLWZF*UEy~{iAX*6$RQbI>`N;kx$Vf_mCIXk((EuwxUBF+bN_v9uL|0=So z>S_!PhIQVBGiR4i7w*4V(dVo`@OKMRdp+@y$LC0u(=`kgu5-}xCGgj9!tO8_tlTcK zy)Saw;bDMlJL+pxXfOGy;p>pY1tFBom+Z$$cYd4e-;P&WPP{)qY>j+N8O_W%tEAY0 zv{){zcN2iNbqn;*4rV?^R(86L!d;|#Z`>d$y0H&qvE$MKCD=I%k9GcjM*hffQyd%PTgXbhAcz@r~-}?)$s-=CBgijVH)M=c`|ZFZheGoU?6o z*}+{c3uf6xN_k)RzOq1VE` zsE<11@r56vH!{sN*t}Lpu-@tdFCDYA^YztZww{v; zb4dI4Gf#&i&L`|G=f1qTG6^Nftm9#VNlyFv&LwyjMO=n^MjV{k9Q9dd({jY_GTuA& zl1yjix<;T(xy4LE5PYqKr?ZoqQFKR$XOFDDJg^r!DJV?Ae{t_utp4(Ao7itQ)ex$V z`Par#6Hlus$4~Xc*uf|K7nS%?su%3c`}Y$dHOWH$PTXdHx(Bu+C5pe;*yb2>PqUH` zO}dZtJ>ZAeoHIo3m4}L~(SCVoo@cekyl*y9P}JNaPwzfE8E^~@Bsc(-NCh$O-7r^O zCOnFLzSu-9=#?%}uhPF?_}m}`v;W1W+7xo zxt3qY9V@{fIYeM~mMOl3S)5_uktAs>%gHBwT0~|A35nmoA2#Ib5BD7+=zsHTGbTj0;H z#qd@dMo~9+fg^bZp?sRcXmDXXM)#aqgkYVGd5x3_x)uHRslZRQ9OY62xJjnPChtwg zJb@GbgCx2vzF(eS3Z{O2S$scY$3&Q=^&xQTG|R-fNItu&NRc6p7k3*c@{Nz1k$K)g z(D}D(6vGTPly7F?y;I@O2Yaei~0g2`&p{1`HSQF*z?^rY=68-vwve=$Y=JkgP!qZ-La%?PYGXMK2hjYu>|9! zaP29qGj=S|TJ%7a&&;x3_}s$@oCY4Jnoi*=o@e>iOM-M`Fm!AB5{$^R+JPVqw~~X! zM(y)FD_Of+Sx(E?4VT|kU!pIC+M`*C{X$WbjJ@7_=i<6?Ud_ZV5#8I|waU?(q^4Uo z0!@2#VW}1sHLd=uau`=K70DH2Z-`(#$8**9m{`o+bK=BR>k`+ei_>A8bDygCWMdc? zo;n)9MR+9ggLvBb?2Z=L>S~JIccuq&u%&f;DTwX&un=29%Sw!zqq`o+%2yYMWHon< zPe8@0dlx3h*w`}UiV*jHsjcg|3$;`gUH>^?D^|3yXX(~GWfNBt^WvfSrq_8=9REN@ z+%p;|3e!E*LOgC(Wd2?Lj!C_AOS{Eqjm)ZVsTa#F<&rGAg;5izhHu595d^<9zw>E5 z*xj!8mkU&SuJApiaD(PMjZ>ik8MFw~{pmv?wVAzO_I5nFkY;o~@Chz5$w4Df0 zmN!vzsl;M}iD`W!{@u)f5d5gzs-hbQrSP6<7jE9;FVKnNjCZDX7m`|%95W{j^oaxf zZOoU{Njp8`0{I~o8L_i2laCDIM)jD(0>YNxN8KOcTcunGu{lzX`joplA0DG0zIBM( zq|%;!$B~$_H!$vxSJRv5Zahz&H(Hy+f3_m4ytDi$4P`_Av#<$Nkd6_(!1 z`H;WCT+A=n`;%j;TQl*sn+iXLk{=5hKdPSjfr~4vT=vAL%O5shh^s(|xLS*Q#Mb^j zKAB!VdRboM0#hg(Z#o^|Mimt+|9Xe--}V0X<~{XF72b0SV$zErsDS+!Z2f_!v~c<4 zy1yp`C4DABS5egbLIajtxx*_*t{tDt4Nu1K<1D5=Jox}yt#8_A`}Pkvef6Nm|Hy1= zp>uQG-$)8q?hRGe?}Vh@wf4TEroHCv$@#43`k6B$pFUpW5>dgEJ6DwF%p0`-7*dA_ z*LZrg`nTnEPwqk~8)qB*I?pIZ=hClXT5>8YC!|eQX9Z_Eu8{>FhI6B;7pb!YE$F!w z+4p;DuD}vY#StJ4$`wMWnP!T=*ywp3<})hp&(|2=K;nHDrIEK%B)ibh&k%)f zaRve_;TcG*_p!WPUlR(<*>`Je*QP=NKB#WCi>?O@PE8>gIQsx}Y=2^I(2I_^- zTCFbxIF&wVdP#iLK?*5wBDtY_WOqg*~;e?6X`g!d5?!b|kTR7*O?tqCkC0Rrz;@?_*PZjI^beqGI zXtfdLQNK+-hZK3@arG{Opl{=?+XZJL^s+T#I=K#lYYkU+k!o67imlM)>0f5f3d< z?<#3H{0_;r;v;i4(oK4|zh}(Ri<>H(_?s(q#|G!Fy2wq`&35|Iq(eVyN$w{4T5)X^ ziK)-XecmmvRi$UJ%@|9>71uZaxPDH2mh^3T2tj`@=Z^iqiNZlBQ&jrTPOu%05b4N` zxO+`Gk+a^8%@KE;WHN!ro zgrYR5=e^tH!IPctJu2=>HccezpA+Or`Fo6IayvK7V2V%^EJwkPp-4#Xzr^FfgL@Y( z#nWP^a$g2GiDI5!licS-GltnxezipgS=+#I<{!O}P8l`2(GhW%vs>pJJq*X-DGgnN zzRD`Lg^z`v zt1TAUFi-T*+|M)j(kx-?p)*$v`Q>UZo{?tVQ1W&x>O-Z4Fu|J^A6ZK}Z~9I1 zPLjypgvUl}Xu(eF4I!Ah=HTrV-pqPbhT9#pWd`1gAlQZ-(5;9;GYlL6{itY z$h)~$V0=*OR^3qzh4J)8X| zR#(I?37k3P7EQn4kgjx9fB!4yr%vx(U8HnGQ!i;0R+Q$Lp=4c*A#ez^nG_wuiCntZy@257rmGssG@c~Oe2eCmFvkXmsLzxPW^nulecDtbtqMeB zDNt=xE8KC=^jf$`N*md(obV$5Ye|IRqZ1gX?D+MZcC^2wNg)zxOblh~klc=1eSL3x zCYOF4wX2&j&DmHRv-7&}Sj$#v?}_->3+o5|;^v-k0uSRAYzBh{7aPN0(ke~Y+If6? zwu!rlRQo9PHHUCN{6U4}g>7SB2mG1xHcD$F+RmSzKrMiq~q%cJw>vdAqa`D2+ z`1`R%8qKJ(8P*TH>RQKqAC*()+De!$awARnn%}4F5&!)95yGF%8*3Aqr#rw7R}?Vw zd89|Z3w1VsT(DGTyyufHSGBf#$)rr{!+FlgJwj?f&`#Ed5+rPQUJ8n(miv7a06B;( zWSh7GCkJ;tHblSJe2Xhc)@QcG@%Aq=zPdY>>tf@_aCOiCj)q0rlS1dS9q1_1w)MmV z{wpN8_lHpA$#+T;qu$O7ukB8i1%bZNIxQaZ)OufXHZ#l51VuLD?S00T7z92kmeCPo z`OYwX)}eGJ`In=zSAny2jAOxw)SM$Ij_e(7bP{wx!l)e6Z6_M)oIO#Q(&YFxT&Ig> zD4=Qq3>l5KiS}3=VrEzqWy{u#bhaYrYjv7LnGuIEkf2K+I>3WZ)!N&$mB#s-9u2`f zUSuAV#Q4}tSLGjTJphAO9cZCncA$dzs?h{qCW+q(T6?*9B8fI^-ko&hW_{H8zIo#M z8r5-=XtdatMyISxdJsQ>GQ$r$q_q~QJtEJwPd;O%hL1%X7xsTYCkn#-&Bz@g$EnNO z%f#;hH7mq)<4T0?Gaah`>8GZzi5ZUEp}BYR@|>#eA)|<8uzmbl#iHT#I*B>TVa_m9 z)4p`f$R9JzQ>u4maqMh1RXM9$9wfpOag-)SltDh{e{--o)LAce#Q(ilLEmjrI1W5E z%zRY7rXpV0qr|qZaa@_~RXOItF~WHBHm;d+3N=dIDQMhK{jU)|v$n#hiDL!isIQIc zCH+|C%D%`1=gJj00WL({SuXj2wLJM$Eyq=D0eJpPsI$&GMVih*1xw&=N<)q9ow5~b z^*_H+C(VePPE-Q-Y-bmX_RM0pS=FVT9+gA!6*%!tm;l*7^9s7zCwu85oep-1$5Ld- zD{z-0WyJB3c9Zyavo`0;t!`^XP|7ScFGO16JEg(*A9HoTw0pnlt5r|u%h8tHy~IF0 z22C_KS6-kpGQu53!k@X%zIl8Rd-+C&o}l*BMTI+%S0sJaK7pxRe~}|^q_f{rUv#T< zhlN&EJMOrhY?F6SfQ~@`5kF*q*c`OIa9X-zwDhQOX(jLz1N-b22TB6Irj4S5x^Y50{pAHzcIh z9y~n$lt=elp&C{9r(*hiEX>UJgcLt-zF^{`Cx=)R)Xe^&+kxW03XInDttxu17Dek7 zzt+7wqhnMA7mJ@gOZea}WY{oJLZQylD;X;_T?Ail9v%2Nf6OBmf)*379;AZaYECPp zE=W&0XTtoQE4auab`yyokL8?)+`bPqRAbF+_8~wOLIOCZ1;JC0A8GFS%vm;vIJ=ZNh z$v$+1p(zV@_32gYT{FP>vWW7?Vxtv9BW<*DXUaKCv(61kaP+UsBVV*Jf1@cym6<7*~aemb_{vkHf!1|&TfBh}Tjw=_qzGL?C&lKz58)2PFj2b<%RX}fz; zn$8(}r+*#>KXp}dMA9Vja89%;rL;efkF8|nR*tLL@F^Frgi|r&D8kLR2DNH@iv~q3 z3NOyCw5Cyfe>i)dRP5CSQS`p=rxx|ltjJ3WN38kJL_IuAV%u$I6Sf$~$k{BnEj453 zuY=O&>7GjJ4o9ew)J!Y(H1nW-^d_<;KOAuOgn*;0-6sw#_^kxS*PLknR70u%x^g_o zDI1U3Z4aVSRs59cwci86wYYP}6Qhc-V&ukUu*`>W@2s-Sp4eiYXH-^m^**$XaZ}IUP3XPQ`diY0P!VI&I z8KfCABe3Fy$W>?N$43u;tE5fd{6*ePFt12Ve$iUuvwXj!R^y4Ffbyi6(CD*a*I*fs z#Wu>BG}jCK^wJT2Ru$bm%Rk>7*ae1Uu0IHyYO+71WqJHeP5kh?tbcVCrdwt%&ihB( zjO+gURD4{>??|ZntQx)j7{|J=MHyWYh9#r@om!6Ny$&t>Kw@g!Utg{nyQ2 zf;d!t+`_G1EI4>=pNZ%+kbu%Vv>K22dbW|ZZz3>e6!LD?iKBaAt~plI%q3)E zPXsdUR-+p9P6v0P{}Lx=7{Q+t5}Ikbr+hwkOAxxG(&yJm$+lIEnne@P5R-Ks12bz2 zyZT*8%k}oST>UL5$;Hm~lOH4sd69Se4Ft{f>h!THLx<6|FaAK~bCg%32PaVXv-*QM z(hDDVN6{Ag63k^uX0(y&t`o6b&@V>Rb9ae6R8%@$zwXQu?*9_B@)%OG*s;~HPplV(6O&9 zZJ8#5e!Yl$ht7f^J59G}eqg#7j-$w=y^7^rg>N1AV~ zsvqA4hm7yo7!L>f#12NyXNor>zXnEB_?RDrH-_s|h zU)h4A(M5nW8#BB&ODTR)ZjZO_;YC%On_xSdb>v+eD%b*8dnX(hmtMgYo(Y>_IWnX0 z6O6{Lz^^O`mCk`#!#P>CaA;BMeykQLcg>(zR@5Zww+DeyF1O#{m7cr%yigI`7TR>; zEa&voot0fI{&g|65rOh#0dSLKr8g%(iS&~FcW7}YqCV_uWGe7*Bl=GDjpMr*p6v^8 z5uE*ZBmpM6Od(BK&+&#N3b9Hjv&XV=a%e*@r=U81_<9=kdyrW2S@zZ){Yb&LKIRX~ z;MwgmH>n>ZyFd69GGStZWmHQ6CR-t9PN9W|qmf*hjYSy5zF73zd5ud28&B_E8hfQ( z(HHp@^OHMJ8(H_Gmsq-;kL_?1)wOiX2BFAfWC9nJd%`Lm!?5fRicGKNfJKU^+|!o$ z&8L4|)1}^gP!u4p90bQ_%X&QTZeXvS@1KwEh3Lzw&MRKD8zj9t;Jz|?DY0G|BBE}6 zC^_e7bfv%&Fz?~^zRyGWlz(DaDt;t<_n~h9Zn~}fhaTXKayGt?g#7``iZ7o9^pF&p z7Ql5^%69W#FN5XLsqb;@h>1SdZus5jiksuH&GWML8|lw=DmNrGWim4|R?}6ggPkGT zjQbcBADNV``^F(go8{YHTr@|`nKC?4rwSLUQ@PbeFK0g|WR@tE#Ox2!@@TtLei6tx zvZ!9UA=sFVpMh>&d0~`vvJp0(!taK0o*D?v zRmhq?uxyklw}V^7ywOu5;fhfSS8>lkUPgE*6!PqP6u=Ccyn{sYCoMx)8=egMFv$VRh5^-T5%@{#)RrA;J5FaJWp%D$ z%O>0B-`#e;h9+m2uyD*60gJ#9=+7p(&7qRk*beHsubzf~w?2Zd-uf??L>bAv-i_S*(Jo!s-puE5|q2yOe>c zK5t~=#6X2i`x^Cwba(^@UVa4*t2&B6c&TU=U7u_c(8bf~#>Gr)-dowYpsv5rPditg ziS1*)1cvn%0k495z5K_-y~(r6A?}A2Mp%w^y7iXOf}(*r78z|wgR$;J;>-JOi8MY1 zvt&0RY2(d~!e}2tLz@PQ{b5m*f`~-Hkc-xeJnvg^FCK+Xe2#CHdT=@8skp z9DR52^RA(gbo+Kab9myYwLf+iSdZ{xCe=zX=Z~AjTaBzqWT$iWPrO#F&3^kW*C=5bFYs|VsmCNNB*Cfi7*EG7mmYgs& z*U9B634ZNcOQ$r3mdh_h`Qpv`ekVE{`dbleJ+d;EkLI;RvjU$Fo{12*;*!$?E4Ls@ zpTRK+@pr)pzu4NNb=EI2>y6DD-^KGox8EPt;h{NQ3sN{PjDghx>q64t?zg!;l=#{2 z4;95MQe}Dk!*` zR^T;r5gbQvYkc%^YrAV%kr>yeszBn)L+e^0u{Va~+WKaFdVGI2f&EI7O)7a#6sJL=Ph)n?--YTr)|A(Vo&p zW;cS*6E9q#OGMu){hqble9m>`lD2cjOsZ|4H?UI5d|cq+P(O!w{YalAN+~W!0HXbw z{p$RlG+Q6FV7;atRnKV)6YZC(Uj;4wm^dtJ>Rw?4Uv+I2?^f}@69xU`I9964rWrky=q=-%rL@Adzd zI%*bC+?qizJ$;|MH1dSLpNFzA{Ue2|TjM-zn04-3V@GMeuw}v$D=&?8>kI94?>;_; z4pKbe6>~bgBW@v(q}WoYZope-kmYNlBhiVb#zxh%)QHvXw;)6~fdJjX;|k?7Z1*Co zTBmxq^kA~or0lVrCkdZ|;A8!NZh|;-l;E83jY>KqTgRKIugc4|?6V7Y)%f!W{zS^6 zuFuXbh%=G5c!*ep&Hjg6;fPcJXRt{^8N4B=fSyom%DvxSL_er#mFRz)sGN~}ThQr| zc354=c`5&H{L#x{yy>IVIP&?upXFJERhqqbxbm!Li=}}d9 zx4cl%_4s3*G)4wXn8C}?Ntt^@b&QaEkTu=)wClw%-sYdq5QgYtop`OD!D*DuLCh8( z_#iroE38dx3gx<(8igW}+q@f|9T6vNja><|T%O4lbaa|PxfWTH(`LLq-{2Bf5wXOs zBv}U8;xy4dc^qH*F79Gk>92m1Wj&@_yAiirMYa;0PSjQ?2L;WHM-KdjMayk7^6Fdd z!~={C(#gs$&w_`bGh!?f>lECx%V=rFpCI5Ck}dxjFt$h+=&w!>0!Sr86#_twI3v#%XJ|-&_Q`F8puoE zNpjP9Wv|$G57NSSeJlQ!s^3I~HLQf0C8~TTp?c)G1Fh?#lkUb&Dw)fpjolv6&?v{<)&G0Tks{O$ryM-hgkk3 zroZ3$6KzUrUj9MvEB2r_hT))Y*&&T@{z?6qtsac!K*!*0?ihNVCD%(1Tx zy;QNoH{rOzpCVw@vV1Vo>#WGF;*`=b8xD3pb!M)|2}VsKyv9#qU)M?Cgo8WKth26d ziKZ!F3yVt4c0I2CC(!{%Z=vIw#godmj#y@gpPQ-DSmr9TyQX!`s6*IVyrk3Rfh6xm z@cSE*%bY*et$_iOY&T#V{RB(!o7dcCEI*{#8P`g`9wLr=fz2U$AGgTqZ~t z!}a|r^UqB>!2f+$8{}Bt9GC_ZG`!J)i4PvJyx`eqyNUl+y^`Pn#4MhS=K3O@WW`8;-_=zxtETrJPhVDdA?p7;i|6J z^j^{Ibm4`g=<NDRCe2kjQK$TzO0D`GVP|_oa%azJsfk}uDw<`7GEqb;*5Yf&>G>3*yL%TpO7uQR zej3poW@#08k0<~qhxn@{BYko?oITIByw@ZQajrz+9@>=`s1Q15f!|~&|GKlo=zbp! z;SOaPRiyfhu9`aGNtE}NSB*!ZKn>`sGl!hW)oAJfqU(K$Ld zQBqlEl28ei4yOe(S*TI2Dhb&_^(!2L@$mn1dm8rcwuijVNrUkWu;&r1~%;Lhfem;m@gY5H7Q5psO;^AU}V2Y1dnKGAcAKp0Mc$s#%GsK8Asm#3o z(37z&(lp0HAU7dT6(2!8rhd=*Ju%ZcI^K$>%bnTawOOI4O5z<>(M#_&Zg<1BZ?Ij? zNV0xzOIclvHAacq2hElY1q?ET3o1OMpgm6twPJScmRqbo`}@q;^=dU{-5UmPqJFfo zaYxefw143*|6+ssf?JKLl*W*RbCjaG&|TYG;{>nEi*=%94bB^NtNPW|)n_0dp$BxT z5J;;8#9x;RLXU$$Oj#gdt`JB$E#&6d3*N@R3l}2VOv`oOocGsNzW2A!0ikdUJpQb8 z0I^%i*ZB9X8+iOZ7MvK{xw3rlO~<4ra|yZPoGT4GL(lopJ41m~bkQu5yWgnTe%zFM zp_}sUlBZ+}_f_`R2=Mww{ie)z??Y=Enhr*}Dq1bCmDJZVe}4wb9`6qfNNv-UkZF|U z2t~LTy82tQK;()kP9}GAjO>5R_&+!Qo$={Ez%u+bn`xpUU_^60J-se-!LJl@#Vs@P z*&4pShvjA+YUyHI6J{|P60Y4iLVth%kf2=ok8^<(`i6$KHa64uzIl6jkq7waSqWVM z@10=?SA@Z4H_*Il$cL;k!!P9m2G0fh_LvJAmAMaO?o3Wj9vvalF5Db5aiO4~h=_=& zv-Mo=PE_Q06hYQ1L1X9RBejP@z~OOMDS(`GBr=S^qgPh z-7Cmp&(G5oK>8Xli$*Ogmm7UmRr?wFLoaGty>? zjEd`Fm$)SkH2WehJ>OV){1^56_mzL9=>(v`Wo%iLAyU!f#gu-;tY} z8_GKU{P}ZuV1^~L78BzSzoTuoXkKQTQ3=|%)ooy4q8J~oquMWD=))E9g8Ainc}lD~ zh$drdC+twJr2B@HOHXz-J9`k3`vp579F7@uWhYM{H9HB>hc1-zfNF2Nsoqc2Y+>BNjnaof@3*n?C@d~63JwEt zNU^FThbO0ngoGj^Ba6$*Fb$qsnUQE0?9gbDj+J!6P3MgHjLgg=K7%L|4R@=Q%*+)U zkMc9*0X{5hYn{+~-Hdr=W@evXPg2$cJ@;C?eSK#?cgSkIy=8La#*L*~YP}3QTiecP zXcK0j;0uHEVtZ6n)WvM3ANUC4gN1B^!tD3(Vy|78jD)1*@}78I0P0=$>h@s&M}5A= z(NXRF?w0v468~^gm1ZXt5@tF|!1SDvACsv!kHZ2V>CV1_b&CO9@e zJ`P?mj8^2Jn^nR{a^=jdZmX)R7i|z6#fl}2zR!PoM{*QvK%u&$6`l&>o}~2mtBDtW zTiuR|jQmqlRErm5ploJOh0hS%+e2;??DmObzFZ?~o+(HCo)WHNj#A1Qyer87>Aisi z#s_EY{rU4FbJvfVnTBCopT54n-V!o@T~VP_tbI*A8V%cBJ^PvV!RePPz~1>gipQH*7-8F2m0TJ`$$74M~U_S`V7^eKwbx znu@!qn|CymLCM(I*h|{CxA1F4W!=GiO$VB6n87zt>Pt~d1gEm<7ct~=#m74Q zjJ;0JlY3l$sxdwrlm=k^jJM(Vh%~u{w$roAVLj`wd(0QpahduId=d_a58((KHgdOf z-)!8!f1i?y%EIQe=Dj*izjGA9Hit<{hco z+dDdNYiqlbh!9O7We}D=8U6(`3!>lN-o`6u4Iq#I#5esTFLivd-M|&lGIbwz;lhPU z=RXq6(dFgkB_$<&eX0b54}Bs4Pcf^>x%u>_zP_;1!DIHCX&#-@va%lGdBa9?pQK*(5CPn2t@#gFd2-lamv`5Rg&zVKow|yb>{L zosp6({C(VQFa|Kb6}I7L2(2-8H@q7G*Jt91ZLNEe{Us zZ|Rl1Ozv6U^3XRhs8oMX8ThTdTtIbr2)i>``8qT-)Y)$(E$v1f_+Suymfum`!4`hG z2mZ+D`+Yy0Tm9&+#qthz7(U+~#YD`!I*R!;*7WE51s`w9UqM|l9#ZyI`r0Mvy1LXw zihGauipRi`X6)VFFeBA64}i#w3y5XV=OHa7qmySp78el=#WMQq>cqu=N?$oIEG%5m zkIA|Fc==U_o%$VRr6lw1#;tZHI@rrto*<7y!gwXy#N6E6;2?Xlq=dxO^tAX(vO>Zk z;d{Ly?MP=^44IMp*>~g$gGj)%YBCcPD>MA<3E1yJ>O7 zV|$OK)psw$TS0WC8W|lG77#G0(tnt$VqjnZoUrlPpe>@w&(*a`imD4Dc0S1t-K@b7 z9)yaj>R1d{CKtsaPe z>3v6ZG;PiF?2jLEJ&;x}1TeZ*QvvY~Id^w=1B2;roYu-4_A|BFSyDfzs%*ZVlPg}0 zPdAfO8$lcr2{WsVavM7eBMXA$ z46J?t4?EMixVgExyAN{$tai4swT$9&J=fdaF8ph4jR7+t z;D{UJNjnQ(wFj2eD*$qDzI!rR>Z&9C;NdWW=1+Ltjx!Da3rV2goh4=p-sI=hPPnlW zBGC&d{bbSU`RJ-DZR*%3x2muD_0&d>kl>sKKWkvyv#JZ9Ei<^V^BXg$Fa{|Q%o zLuES4%uL%cGh?WwrNt4;$i`-@rx&}Y|H-2FL422^+4Mo&Vh5N|0YiAlBFKi}aLs-J zegOe?uK0jS*~ig)-AtX`Jq=H&%8bbBL{+H|&6NR{dO_3Jlo zoGRjw=$aOs^H%9Z7cdyiIywN9MRRjTQ)f=@05y7M&o1{QqmB45tz`7Ll@&*^g{|6# z9Ty*;hSE~rRF$CVS{E3wyZb8R7(jw6=gSvC9VTgQXBX9GN))F&Z%AvC zw!1T|z6#G6`TN(y*B8Am2|}cqvKrFa-o7-Lu0Ft1_l&9eCJ4Qfr?vgJBADD2dVU)peA9Uc(S=p^C) z`pD>o^b{V{Z#Kr`E{6ws-LYl@^%gug%j{!8LBT6$nqLpLzyUm>$AW+k&}6we<^-Gw z2E6GM81^=%S8>*Pp;s5z4tR1wF}V2i1{0H6c}lw3D-Vyq>ywrBG%?rN*ap16Ws=Gu z3LtH`8gYkIDhyPM*J+h_r_?X-(?uefK0ZFazE^->R@M&~f6jx6d!r^C^NzYFD%UJX z&`*7qyF|E(ugRsy6+oXMRHCAz*T!R_qq_;jW487ez=9*%MwlspASC+){(w@G74}W7 zfcCQI(f;c4_t#mzc`pks2nNF)UKSwK?R=&Gl#^oy5|%^{78VxyFrYbLr_q#V09?+H zld&s;G|DPEpsTA3M3GzfPiF%nnSG4`^%he0@M#IO2VCA^z{!V&gitnN_=3dzjvDAq z&CGJj%G9an_eh}N5W7NC+SDY=5S}kiIl}+XQ@47y7blY%_FRk-4Ju`8Uzg@LO>QKB zisBsmr@>#~sInRVG?-7n;NC=Hp$fPM3=O;s&}VvTYUC+&a+URbFkTqv-zbHIhGL~i z>y_|FyXX`&m1T{tEaKpA-v`lPda$4hOC+hy5I7C|(=Kkj%;Cd{=`GnX@M>pk6}Ciz zz(+Xbx7-Z4R38)MR6mR7P|^$j2TjTabI+{QmOj#ScCI`v4#&z2jf|3*dNy+K=9QBm z_J9S_o1Vh>OH3}}FCs;egMFa8n*&{&i(2*;FQvLNO7~D!)?t@5McUNY%uL}Q7mUxg z>Yy>MsI2k+wZ;Sdb6=kx+D~tU3S+#hqP(DPH159dx6h1Y&E^ty(t50QinS(?P zZR7xo_yR4YxdzCPz@g8b)WPblLcO)Wn&pk21C~jyE=|cCSE#pKW1zLyOwHap)(;Xw zg25c9W{UEmy0x?RRf0eTI*j3pBVPL@&!}V7kTqYbgarlT(0kIX0~;|QWdbm<qWJ-u!1>_Gku zYFzQfMGC-k;vD>V@yF|vzd)V!LXrAm>Bq86p6xC?y<)wd|L;M+=#S5SDH8F}K zv$MBvH!Xj~KQT1)sS&#Ixv1y?X+A(sF8Wg}$kA`oPhcrteFzQ?e#M`ET%VSAmOOxp zj+GwAZ(EG>roEu``KrX&D3y*BYqAXhL>YC9j8d6l^T@&6FiSR7Q|=3Ug?36K;J$d>&*IWYk$e#f7Y!+Uce-mq9*QY^lVQ+AK3CtFB0a>(Lhguwyvy+mNVD0%d7cX{2fx-2$ zj$-&YRqMPP1xRG5ZYY@<%$I;k^0uTQ9yAzEa%rVl!!X#gO{*8)k4to3lkZ68-9?_E zF*PwUF*pBQRpn|xSKDVfJu?FpWvS9HF*7sUKODY%`SMy(V8^2PJK9v=HsU3;PPprK zJL=$F)+~iqV>z#Z;_ko|{~OB{CCJBY+Qb3IDzkU4&zk)=X6r>oL{_%V!3)D_06$xf^-b?XuZMP41Q8YV@K2RbT`Q`4=Pd#KtE-H9GPv63>2%}M-(Stndp>JU84({k;9Spy_GL;p;Q3$b z=x9fid}KV$8E~x<<&8}ayw+zvXCHU5xTyrFpJR+#>*@CP>&ygok+!V&och4kEwuh$ z-6qfNytOw|B0&nY9E{A&Qq9BNn^kSnzZHwGNsJND)8cB6U*)rCC4iMz)YaV!mC`R6 zYsf+qj3lSBCP5!#jQ7ZBSSt!^dg#9==zDy)*C%;V z?S7)Qg9BZ#Jji|t+{qs_?%w7yVq;?JXGP*ck{k>=1(e@2U(vb?%F&nm59CBL>z zQB5nyN*oxPe>{; zp_w;h1h~L>nX#jBQ#is3?x>SAB_KI_u612Gvu8ODeZ5X`;P-Tm1(aol z$%}RJx10FHR*c_4jtQoSWIg}A32_($>TLKt2(DQ6<9A+^g!H@olONES>8Rz0W5ZY% zP+0LAlol6*)W2c?pI=n;JZf$7j+bC+B=@_E!e@R}jT^-a2gGhBC7WHimVuJZUALB` zA<+08;*32b{&~z9f1Qz0%xR(Z=(}_bi-aV>aPxC>a&tn9#?JZ&OIzHfm!!LV8BO~V z@1O#@3D4v46W^5>&sFxQO=5MZJf7_Dlw3RPO`SUXvPigNdT^;y|9HJ}V7CgL_UxKx zwpAM9XgYK((S397A9;Xo(mRwMkJm$EFF!>bY;{;VnEVX;Jd8Dbu-6dtD8!_yx;j(F zSAX{k8@3kP5*aE`WqgEBhT`^1#1wNuL~W2?KB6>Bh*aTRBzRTI8rz8&+@ybFXXlIW z;)+VmR+rieqF)$PW=o`SRhjw@ij3L!pLNx;WLTn5Mg+ig7%ize! zyr1~2V3m7e^$?*xl^AC(h$VQ{l(^Ix;$KZ;U+hN`($dlnch4m#MOiXWhUbvOSnkME z6Ou$|_s=dE9}|-SIlbIJ)oyEY%cV?5N2lnmy+JV@Ep4W(pAoeHNS%}k+re^a5Cm6oj#GP}z7s zPclSQVbmCJxi9~o{I2APUwT^ihcIruIg-3U@LIN)@We0ij;5R%($(Z1kRF2Ug_jM! zAL;s`FR#h@__8YmSY{t^Cr`q%CPt(d5ITb;&5h z1`j7BGHw9W$q~9GX2tzrmm<=T*B}U84Ju4IF%(}Q62R-$Y4Qreaiw-=_h`n`X zCC}4f;-_(-Y@OFTWmWajZ>Zs zE@`^HZW1SvY`px$jR?527Goy8nX4ji^YS?B98>BHN6bbmzj5Q)aA|oLFJ1(-ah)OW zp}~k{W!2ZO+}zxZ$1oFK(3fy%+_#K&x>f(>;)EZMLx)-KFb~NZEGs|%{aKPSo3G1H zu6=+`<^}f6m)GyQaH;IN&X?;(dXh(Pz;`JO35zZgQEuXzAlvK2xN5dpn<&hFlHe0X zKUlyaFSpBO@J~f(R?Ty z>(6rh3+qPL1aB^yNR|G?lrD4oS(HV(PVS0*0w0~{3m6O(xP&nS2bQ1Z4rl^MzOGWd z3Uf{IAI2uUR=p@(kd$sUYh48&6#!)r#(WQjQXVp4_L%7r!Jh>E~g++CMnfcYt7vme52J&(JIlaIF~MwsuCifz0ep3 zGUOgTSw6#BIXW6p!1x1_bxGs<1D(<<<*xusf<~h&psU}_KpB_aX(Jui^*ODv@DG4* zi!v{M#?MfyFjwYx9gDGNz3*NbQWr7cud$zv%SE-!zmhoz>Mhp%dLB@q{qxt}4y3mD zOg@!C8hTtO6QB@5W@MF?p8e&O`|i_Iq61$s^yIc_^EnDY#5&$#mE>+Rb($ZgLHS)@jaKK5Y0b#y7?Qo1wZo0C3V1$hg9K+#optIMdE_(=_ z+rOQm23UW#!B@K=(FTNs_zq~`4Cc}%I26AYOa;w`x`R!>V@Xnby_jyAyPI40l%ZRj zBF821?k|;<51Uv7PZ6Vk_1no|JN(-rE917V>+LOB z&%j~W?uu+Z;*USZ#ps3P}W500q6sgN$bbMc z@##-_R(QlUz*7wi?SG|1$7T*=K@*QWhcQ5&W9+$xwsvB=m%G8YIShu+Sr0=|`FsUs z$eY}gsKUv`#pQr$ELnLCjIll@5TLZrY11Ia=QyETkf}knO?a&%tEVtlU@wqjbT$66N6RS*wB!?898WNCSU&Zd%%l@9|PWwJ3MHH7>bLk7P^GPnc!aYGcKn|U`@<(j;Q6sy-Oz}c|={c)E%0uO?O-`=dd z?7=+UiO=Wd{F?LLM9*$6L`f(5guA(LgH*%vm~E*f9{3w*WS%p=s-E{@p?)#^GS{0> zsftP4y^Yx%mhK|`Ys*eJb3qol>)N-`^HCR=C>)0m^(@($L^@>07KX24R%gn)ovxh*4@ zqJUAp;@8#D8K0WcPtoN%c|JE#h01Y+@#mBOR>Xhn;6IA^zbfi-0Y>s)r&fvcaad4+ zTs;Y~AgJTUMMXsoxRX{^EDyVvmo4g?jE&iNXaGlNnsN01Z33Op+o`-kVyff5cY;!~vXW(qJ~G+3(AfXktA&@VjJj~FW^zZF{If}7Ld3?cyhPIgO{{ao?I(phrHk1rQ_>USP;+CCy zPv+VDu@^riU?)@%E2@}i5=39tbVS@x$Ae}!@bE9jkSDEPgMu(>P!@bl%JSWvTtB+b z-s(IcoqYKFSrg}tD5H9}C>RCcli_(6*zZ4hupFk8HJ}57m5hOWtLNx?6Q;?o7M1=) zu8EVGHcQqIF)eil(w$^sfDL_XK_qieY2&bQJFG}oT3PA)FgbnV_A@G&dt=GT$?BO> z*J(pR|5Ldb1WO0RusKn!oHvM(h2{6JU%D`uG~z(4oE9(y%6Xe79N5ar3Nq8n+T1)y zm#Ta6mQX;rps)KiJ|h<~=CTI-c}d!j`k_{WzRA`wYA3?l==SPBkHs#xMkeD=-Se)f zp}D!zCip*)QHjV*Y`qQ`4^$;6lmyraqRS@V{N#nA+Ri z-2CT{BWL`J2PH3y239YeAy4Kr<{Sn+*AMOM>$aeTSy)(5@G}6&s=^73wG}0Pn;{&G z>l=Hd0Wd`CL2@jAs!Co-iQNDICf$;kC*Ei8($dlbh}mSG*Or#@+4Rbkz-WHR9Q|FK z5pDD(iGb_)`+&4F>xj-B#xjeR78Zi~dhsXNfMT!l;K75s*Qk?dyhlrEc$nDnaqHe&1!s)OcuaWfaB9(p8$&R3+xtYVLf|t4am_ExX=x-Q(zqmS?-qwY;T(eW``x>DAc%NK@di-`%e!yPOjhSMmQez^ zwLHz$gd3WPF~4Nt2CX1w+6(Oc>EbzAQaAr~F;CCb!;2r6693Xf7t+BHlrw;Zoc4+a zyRK08%wU;@7eiZC`!jBhfp6u-xU#qY`t?RxIh2`8;lvFD>~ioeIw^|9%LH^%$S$yE4kTJo*0L5Rn6;ISx;(s!~7H-2-)QldS25DU00 z#sT9%8@!&2x_Nu}(&hkj2`(Q}A;jx2w$vy%32~b} z2)P-;L4K^D`HtngM`-KCQ<`n0_WYi7?c~k|y&E{VZMW#h1;rw6@$BsQw?ck)rw%Ko zY6*US;quR|DFMH>o;Ej}3i0F!8iZ?a5VPQIhu<+dS!yqfyIrQa*>?vyA#b9X&R2h2qwb+$H(GOvSd91;w+g;iEAT~1m|jS1;t4_6!hEiDR>74oz6MwbKzrn)%o zi-#_swWcwpiPYK184}`aibyd5<$(;CC}gS1`L<5TcP#ov80W3h5guY3G7{?M>f@`R zPl*3g$cfQs5D#SvW`Flh$;qrzp8}5iPL7M@o1ng+rdrGw{aNiXLojRAMGWs}KHCdO zC&HBuySX9wclJYE2cz0nRg6{8h!^sFy&QcK+u*V2tqFJv1@o+lnz+SYI+8+X*!wYxNI&)XM6er@(sl-MfWL>Sh_V8q|>imq2Ri(?N}vb^Tn`H z#G9Og+Z}U|w(R2DZWH58wBr(D?3}Y1fSL`?pVR0rDBC&>xH1ZEFO(GDnQjw4ss?2C zqs|E994uu_l5$M~=<~2SR?q4hxlFJwlIZ2a6;N61po9W=SD%>ur>SGJsXk#MT`u?3 z49c)l;s&n1Ah?lvTv}2j(!66$J+0LX2YFlfsQN1VvTQ|~)KYnZNMg3a6JMmLV%ixeY!-Jg$@1LEQi|%zq zIAeQGw}}@7?R@`RQpthqcbtR0C3QziqCN6$0~TeNGPM)D?KU|%VxQ%{h71o}oAcqB zZOaA0V<$r1_Kt4`2Uv-WKkB`4bpbS;RorF1!!O)zVzt9aJwDtdNm#eO6)ny1RTGzn z1f%Cm`ddu(mBiYhLbpPwt`%Dnkk^dmz2 z)DtJ-isJ+FUef);SpzhdO^?`WrSf9dz~YHkR>x>m?kQDwWR^QnozFu?fF*N zwk^ih`rw`$7LwGNYXw!O`@2}@QK7q)yyY7x-Xq<^m7i)jpU}JC)hLF6B1t{;nI`J@ z*BaO|4u}>YLJkf=b=4F1m~z!=)AaX^`?}eltGfIk!sX}Th3W2%zc5%ROhH&ymy)*2Ca%}?zTj*LZN2!NIAohm+0UKjO%hL|b%WbrSynyYcMtY67Ohoj^v(-X%T!+m|V6CJsj z<+l6Rzy!hjhw>OomYp;N@p}EP`dTRF<$W<)62doZ82k^mlB2CRG)0CL>?&4oEk{x^tW)I?LS=OpfYpmeVsVGAxr6FRt^PlC0 zjBOAZi@fZAYVEY>sNo!$YeaP4gqw-mObx;ZJ9rJ+ev+;&pKwUy`ERq8PFuJNg0EQ( zrxH4eLbU>(Pd;Dk_k0T$(BbdjS|roFTK3Aw{aMP?+oR@Hku3GQBU}Ssv>U>FW0(6U z9}k(R1_&Bu)uh`9XH|XY^oRG`$nQ*LZvPY3oF;_eD|XZ7!%9EF!9flalJvk{3K?<8 z?NqxfPlK=1(D*t-wuHdgu34UxRjr=T!NG4+3=SJYC7HLag;?4kqXc;3J0ip--{?8Z znUF79IrH`qO%$C8EZ6RpObU0l*=6`pD|^VJnQ?TeroAG_*oh46knWj(_zTC~<4(e- z52`p0A!R4 z8xCVBm(U&q9j15cFF<~9^QpM7iY}xNM=*ILQI6Z{>+|6Q z%k#=L5j}={Jes75GU2!pezsJOP3L!zja`~C37R&Rk#vHE*)uJgwd0GNyK1KM_o2T< zO<2Yq6SfDaj+Xa!$lWB~Lm_S46LRQ;^oY|Y!on8zzW8-zXOGtO0jileQe0<#&9W8K zV){1;;S0SnaF<2v@n$7jW;6d;oX5u|1a4RMu~d0T{l&{J8m-dda!Yr50_ZcW_AO|NKH`=mo?P}yjeKHo!ZDJrZPiycch zBP`)SU*k5LjOdow&gDVEe`%8ryd33;+R;yXM{iZs4xFO0m7HL$iv!r{=GR+S8Ma9E zJTb1&4TI)c>7MNur|&aun5$O{XPX~3W)ktK&P9RBRP?zr`SbQ&q0f*4A}ZJd831k9 zuF;&PEtoj6m?UqjW%Kw^-bJfEmaoaMPJ z@jFbwV*qUc0(92vuaXK)D?F;!d%yN@qZddPC?}cj&S%X5KGW=E6$`8trEw#;TiJO@ zd{UKNy{b*6-fM@)<^MfJQKeY{dr)mLO`Ssiw{#S1 z$=4_4V2#Gm=SgRarVQa+*HQl&1amSMvo4M;h}Ax+m2(qMML! zyI*VR5G4B&>+Hy(k%uq?t$?Dln2l}yVb>Uf-TyG9@kz*)PqRiUlzTkZ@l75!_7f$> zv3>80Z6g)#w%~;!=O-j-23@*2A${oPwT1y`e4D40?$!y*v1yb_lZRfKI+fD>H`0p( zc(8!lk1i`fB>*L5ColHFVLfu)N2d`V@7O$ zpqNp`zNxGq<%9|dep@BuC+}4Afie5!q?LY3FUMX&hT6&Xx#Vii-D%Ffl3BI3Oj32t zRvbcQB^^%Y5*$jObcyF%qPg}jo-U-z6N`)sJM~++>g?46m;~J+EeeE)op1g|c^FP&TiS?nC%R5h2Jd7y(E>=@wg02q+G{-0tXCHw z$F)3?8o7vab1V%*Br6_qb>o*n#Y4y^Bz#-JQ`wa0eSd5+UdLEgIcBMj2kuONF)(}W zD%q)SLXGt&CNnc}dUc=Ub^*;YSaU`F-_KLw53kJ^Mr|jb4Y*4=6P2b<%W{6I71XQL zm-)-*7C7%*ouN~S2Lk3qWBd_7mwz{Y@2KxER}bOA-$B|i}RVv-VYNY|)HG_w!sM2Yo| z0p=o~t*`FWwZomr>#dha!TTLTy{BeT{*sGa(?`OFnxOA?D} zG^q_;gc}wiVA08v?jsVjHzOVy063a1D^Z1teW|m_%EyU&Ml+Rqvay(|AXBzrad8G+ z&%8m?41A&C3EH@X;{L9uL%j7#Twjq zZ?BnMW*o^-)ebx7tG&Nl61_Bu(v_WHxn->9ZnJAfF)4BJW9lT{Nr0aMRNe7x zRMCMc)>5$fFyLYU%KBog1(gRAi4<~mFNrcFWlZ$2a^mmsxx9do$Oy{Q;?~7fsZ>2$ z7sHvL(;%DOYgql0b*ERpc0$fG_w{Cu!rFf~Ce9er(q+I7d@RY4Zjxqm(;>GijioN7l7d?wzn)j z(f|thhkvQKu#K>O>cLjGR;{jse9K5J#7RNRS;azn_4^*jmxEE4fDL(pIHPnlxv=y= z;eJb6^(s^T>sxg~Woz)5qKa~^nuwhTKvK(NG;wcDt=zX+{w{+Rt0kGX)29X1T_rbd zxQDNgO&;T}&YoNY(PM;@oBadMgTxZ_W>&=Xg4C%;1J5pm3OM)&rI9nrVb)RGn{PX$ z)hqH|r46ysXJR+#6NGnOc6sxoSkKF_5G6>W$^gC-$sjr#z3K~`8SWkRCh5S^bTb4PHW#`PTaIOWT~d$c&xZ= zdXT>Ze~0~yqR@_iAlfx#_4aqH3Kp>8I>W-xPS6)Z_z;ua`@CwgW?uMR#*_`Y0xsc{ z0y21?XWYG~DUF=n_u^&MyTTEH{3wN)fI36^lgs>p0k^>~bvI+MuWgEG!2iXXVw#9d z@RJLo3xXY<9pz#F+239UQ2~y4CVm$ZPl^jtWjLs1Y`Qdjk0C{EasQ#JV=jhu?|0S; zVCYzq4OrU7<*b1dT4x9+Gzg7qoxMF$dQTUBeB2pjnphKDU-|H( zXxM=GB`4$ui3Z~34Rd>D@8{>4ql6X5ZRA0eiX580@%gc@Iz4N0r`?TEm}i!VSRj%g zQmKSeG*!^;#eIQ)xVJPKD^AiLWLp2OKI2OyS34wmgeCxn&L0%^kKkg2vL?2x8QeiQ zS?qqwI7r0liG4xDTxRytZ1=kP{S}u?ovxjwVKoV}+_{!j8Gcw4)WGE=Btw@|VLB?8 zDMfe`iulP|6~%+M`JdyVab>~n2J(6(C%V1AMW_8EfaJoVRUOF0p1!R++GE5{CpkzS zYY8^;Gvr9$%v>}&*kMNw+(@}_GyKU~S5q;!V+VfQxsN7yo3$eD4XO+57n16^Y5=b~ zvjENu@rX2jlcxWzZv;f#&xR+LZ5CE&gV3@Y|w6m~Wzat>k-K%1l#V?eN@oS{o+ zf_9Tl?(et|;Wh0LvKzj`bN`qa&Eh8ULyD*^Xci9zoe$GOfs`o& z3i+XomYq1i=C?~^3Hf}KPbdmFZPwB!9|_@TYSCdZ>lJ7F(9sEZ^bgZqxiaTWS$nhK zH{NRl3YI;s2lQ4KFV6u0@V+3hCJ_B0Ohh&kkzDJb5-Ge-i%;Z9-k?`O1No84iCu5`ZAle_KL-Z9LD z+${jXw;)mfY$q7m$}YzKk#^OPlw|GLa`T5N$fy%Bu24LWg z^v6J%w#xf##+QDw;cmBd(EtyNCGiHD#U~&^yqaypa>a~t#<}&!&BiowA<*VIjWqv@ zV`JO@Fp|Nmm#9~){~WIi!A*s;s>N_#<^x@ti-BieF0R0Ch;c0QX@FMiwOv$uiVof% zj0Bo#l(UcVja8$C77C_8E@!b$amd=z$5AU z(sp*pPn3T3w5^ED_E`Viw`=6F0O;~M8=LUdYFh-r5SY6QXvC3c8#*Z`r~RL{1Nr3c zvp{wuUkGM!L|ISXfi03Xka}Sepxwcq2MVTEGKNo`Z2^J`@iAAyrUN-RF981E3v}NT zf@UrJ1mD1r=at!FM%rt6?_owHW}O8mHG6shMHRdgxv`UBCe!WM>3Q+Xu%&0uTMF)t*HHUu76KCH$9XHmCUU-8YiIyk{Q&m&q!w z9ceE2agsg4%SS>x;l@ZKHsDArh(i^?>>vg0}Y5%O71Dgc46^W^ZvQx3LfiBkv&xbg z3My-l9)tqjn$Ojnq(FoDI73LbticrN*IG1CCOn=Hap)BOs?KgFEOH0>iO4%3+(5X< z{!{Jy)ezNuGI#!1W)8)W zL)eq96_>zVN)5<|M;?tKqB7C2%n90WzD6f0Oru}`HaY?BN=H+wALP!n?)!1*E$UI@ zTr~2Sw8__cf@dE&ya6&U6&`Z6wt8#$hPVnCk*;=zwdK@P$B(zU z=zkpE%5bK~?At{mY2I>HgrWJ8BZuU}m z3=G`D98wvW>3;^nKREE3UOX;jwu};ogElh_#Q39r``K;uKL=x=21yP?Cuz|$LYaiS z$e4u_1}%YwH&?^RDs`c2)3c5FGIq#(X8y4c80)T&c1#faM{-LE!Q!l@uxAe1y?4zg zFR9D7T^F{nVoKIP3qF(lhY|oDdLc$dri>?A+G(T`p5xN(R^A-79so@!h^1~v^v9S6 zKmNXLKgn~JyZ5QGCGB9zTBh_n0~2eFc{62O0#F4I^Rsm}3B_8R&cAVxtmoe|U4cra z=KPf_c=eeKe%8CW@@zQU%Oc%Rcp#MZu7nN$$594wD{)Htrkbox7a7 zv~n?5xd($Cfr;c3tlfyZf2px{tM19y0+LNRCvD2L0Zf#k+PC$OhQbRXHJ%1u~b)tvn)Td=K=f38+h@@Vhb}IS7JCnIi;r1 z{vejUJ6`tna0s*LIrfWv9>rWQ8Rt(Y+SvL-lFzrgK&MS+ocFDH+~=~`Jy;Nq+VGht z&_Q)YuNG<9UxA2@D(%FXGS0a@q8x2`9Ax!L@W>3%5HuxhllBvyc?swhUNAhiOj`@Q zPuLtt{j-maOHS`i?Uh|)RecRmA6;{4nB$|>xaT4(!HY<3nRn4&UsX;&IT9EuX2fxi zC#)Q710F?%g4{pv4)W)xhaFyh^%QI*UTC_1L2z!YhzulC5I!G#3Suq%U26-3`_`}@ zof2bO>1JcYHrv;gDjd z>0_AcMB@L=0ysQ6KD1A&clZ(SnV&xp$^!AEwp$Cx1%Dl+iWQjexMd=zGUkm{AWLHNnJsb3elG+nSOya zdROW|*5Uv78Oj=R;Lw-S^>T{~J5wPtdk>6>BDTG;ZK+xIC@A1Nmlk1$rs0b${xZQ2 z7ssA>1T>iEE$3rr+t#qtjZKGUNdp6@yNsddG*c;yaF$THK2*-xAvN6E2chn zY9U-@TNijX0}np{Zjeas9O2bZ%;|8MsU=K#FKp*B$5)Xcn)07-e&4`ob+UI}X|8kT zJSunr!BC0YrO?(#NkCfym@hz6%@3&ybW#jSRiBjo^35~%mRM)`#d~C`F7}r5!{-*Y zMUSsRpfDz&`pL_>V5VX3Y|=d~Z3^i6ObDkX4?y}9II}SjpSTL!z|$vJ_G)oOI&D8e zIPR&fN=mNA4_|3vKEj2wG{3M6%10bP*@GAVp6zQ_lR`e-!fGRqFoKqsVN!s||i}^_&Hl8z`2S zZTCPUzVC$n-oJfO_dx4aQ{(-rlwdHGh-HFNxtiXb#R`>0Y}?Og!E$W*4oT_Y#hm3w z#|JN;1W~rG7wWo9QXcrSVYQI!StP#~sGXi^Oaq8g#kntnk5G z-Zt%wD&j7hsDOMO>=B?QwfoXdaseHbY{2N2B{na3CbPZ)oYR|lKw&P%Z#URqSY1ge zUG#2;V5RAD=(p&4g&DzZ%d!%!E8DCGp`K=x<)vT9;8yz+D;tmZ!ws1pM7jG1HO>mh z4WC>Kh&i{MwbOKAQy@)_16BZS1TGI%zgoSKg2Bigf%bYVc-qXLc@9*$%#P`^o z?iW@?`RL2iDIjAY7ZsuDIJYpwc=@H5){RnRW*_ zyf#9y30#n3UPfK^1m4b>ks&<}MGcvrP8|Bme@d*#7;Z1-Re}Aj|FGQv_33hf9hn^@ zz_+-5;;q%b<1Jo*Q zpWT}qfjSegzpYKSt!G@`u50@ZrF6t@jT}sqg>qaCqqd6gC)e6?Szm>bY;rHX676x^ z$QT@nw!d9}A^DXPA9z`NZ%VXkzX)~n?}7Fc-@CEP^Y<@m%0uJ62dZly-p4uZR64in ziqAWSTTA}9tb4mj#c;ftZj|(yORb6~V8*&PcNajbu6_;@4^=4;-bepU+qYEmbW{0=jGolcIzwt+_i~R)!`CMbwtaV zi**z2#<&5;1u`tHi<+X))Qeu8DGBfGP8S0XBwVN^i+&+-H@cE?dtjY@!_Gjb-p)2s z_35Yv$whO?5qDi;YHj>xn0RUai@fP7rkltTvF)v;P$``2v03>{kWn@Jp9c*+37^&T zn#RT4e)v5XFO`rp_x;}AhtWDBo?R&{?Dh<-IY~nOSCBUCtKBMX%}EkDP@G(p(v|Re zF^n>BSj_4{o}D<>D#SfsByzLeRrS|2`OCVmuVV&vsb@019k8mc>03o|9ok?2-Ya_2 zoBJein8*9il!LCgIqk2rrarS?IQr9O*g>Y#htGru2Z7+u?#qUoNwyp2Ym0qLVB~Jx z$huHu3UgLeSfik{Si~ka{~i7Vd#nHLs*72Uf-UL-)2S0$>v_W^*Io<7(C13BE1nL# zTk~@FlWT$-PaXjGc}CXb(SeCY&W1HP)y1zouq#I}WA$^z!;crtj%q4_#cG>sGl1r< z!g(KN9}hg_L9BN134*2lOft?k`w-7DZ~to*}DRfv9W=}KO{aya62dgt_RxsWP&7GWp33)YJeUtnPwF6zIsXBEr?m(Y!Wna%(NPYMK z`KK&n6B&A9-D#AdA>>Ul;Xi(lEdx(9WVmzqS81eqtK1|tzRvql->VXqJ%4oYel;{f zY`?K@t^;oP=%|lgH0tHXh^X7FEi`~>En;5KIkZ(&^tzEpUow6d3g>oq zOOx0lpXTbfr-!C|&i3V>nqd7Ax7qo@`ls0WAd-|sU|&bJYTvTeGcAo<=uyqLV<!8Gq-^%G}Z@stm<9S3gZt-q}OcI{SW`6!l200t&YR?v|X;3*0|b8efU zw%0oQC7w(dgi}AF+j!d4H`feL)Hqs}iLc3h-A4LgJL0p5p98in!u)eq{^N7~E^c&L z(KMr@gBo-bBG@sBdonDSvT6Co=GIhf-H0ewLL;Ouf1p7q=*}7JwHgk>=zL;K)dEda zQTPMDxww5Hig32E;h%b?F52KDzRzy7s1+IOLr6byLUWPuyXotdgWPCNU>0xn3ug>| zv}VJ{a64ZbBK2oR@hYI)qpg*#+_tSRry9$*Dl4@>y~bFSYAoTT3X6@orY`u2y?Fs! zEz>i@uhUx7;XKQmo(j+;BLkBk~y#mh5}s0+Q%@BT5Mo`6XYq`8q!!HEBy zD>8tFn~HqPk`oTK${jVD5;m_kS$`r;~j7i@eu+uNCPq>h4!eigErSPJ8d? z-(N+jTmN~_>S*_RVwgJEZ1k4sBz5^0TCj&#p`fm6xvGI!r=?9Kssb6|pPwvz?OeW%#nlgG}A0V|vCWF+P zZls<<`U7<=mwJz;CRH2mK62i>s_s)f9GRce`PQ7q(Gv?^rNqt9qylhRQ+Aq)tJ?nbIBvhRar@4FllCH~BX zZHy&-uKlB_gCMWVOE{e7EipfMeS})k0P%cS= z7DFZALv<`W`j=iw;g0maRJkPYd{*q{?L5E*gJ{48#5`uBM5^FzxyG|&`Qo>A=B@LD z=^V#gXPeQ;`JD%`38!yqtrfhU8i5oDN%xw^7JkMLJExIOnHNGAae4|D(J%DB2MSN| z-WCo4!U(Q^)H~oSyKAS{={^Um$%gdYKGDwigdw`uS1YbyNx068z@!M9?N7SHMfx5qb4O1m|LQL`r7s-@_I{aSJ*H;2 zR*+99dpH*0LR#@k9HYMb`5GY#(JO!N*(c4KfsgJxwUwUrEN>l`Xby~ixX@8O(ep4; zl`Gn1$A#AAYiVPZymRCAwkBitKK-n^i8-rU_;d%-6uo)IiVS^H-bz}&|68;pL4+I^ zg!|efT@*3 z5iS?#MmUfujcw~R`-k(XZkEc;Y0b2QDnDH8xchEO-q}}QyuNWf1bS8ZwTt&|CJi}} zVDdNG&28W;{nmrYUp`A~G;$iCc|G+x(8NF4H_bcTag^nOu|&8LFIi(r5r^)8X^P*X z&49r}H-o2;9TEN%oxUQ^Ma;hjozbx0%CU={ry@g?Dyc?-*-D2pG~ju!3Ai}^otbfK zr6lG`eSN+&IUeoj>_q{`)@k4W!qh&Ea;v_B60n%@AP+?A7uGAq3P2rKy zsN({z(^H`Qg7{~J{v+2FHW1&wzPmV$4SCg<4z z+LrQTILm8I)C>beR^6_S+`b)pM%kA+$NIn zL^SUgaFkiEtgS$WAw^=6V3o^)+qes<^sv=S;~l#CpT!8MUeNzK{(&@V4Zn>}Oj3nBJ`Nl^=bKt?4U8c zhxQ2o*e#rlKp7+@ps6TS9zQx^i3ZKvse+m-{^Vv(BQB1g@(@v-31L}+V;D2+!z}8P zwlnFmBBslTbXWHb-gYot5#AOBlNv}%e?Zw_mga`v|4BM^nE(m(@jIW>a06e+-b4s3 zbuTPsYdT*^-Z?RG049n#5{uJ9CKIFt8JFu~xzN8FB1f%!HAj7auU3a@M~>i7GRyGi zfppfgRHANfRax>$b30bVH>2-n#`i5NfC1aDkkD9z(|*l=et9HR%eDRf_CW@7(-mO& zFTY2RP3wndc1^{V%Q-hYY;#{z+h7xjrmfnDE2?&}M{Y45*m4QBY4cVOoQj)4gNh9e zQskn6g}EsKm6V$@WU?a5Da-e)?l{ABfjmr)@Gh&a{Py*zlQY1*A}seh-@R*8(|6;f zaM7-*p{bv&zQ`3LGjnS{{pVi1J{(kS+hS{ zd*e$_#^dC}`eWZ>`G=(#gdv~8FBjx?mEs=r2tW=Xw=|LzM7&B7zyFi)Pg0X#)7knaT8 zzA;f%)n%c+&$b+YY#g5on*C{(obX z60Nf@vHsSiKtg7ye^K4%BJAHsQVOUf;jG>dvSzxdPe94lb>WvCn%|%kvgdDeW~1bm z?2}A`)?ChhP?()lSnAHC*PMzGO;ueUNLOWrnhHOLI8nmQc)K{>LZE z_2xm3L(0TuC?D1CLkVN}IGC5fp1?pv7Dey>I}e(Wz4kC&lD_A+yw2>6aM!#m9x|88 zchX%Yew^aS2KGcwLs|_qqJzA|3)KuY72=^U|LV{1M)!_)Wy3|tRS)rqCYfNhCZA14 z@FogR$bsXY7vYosLpb{#1P9(2*|vh=SH7?;-S*N)@=*(CW)2*~6%}9Xaj=PSyXr}WcU zXCe+cN1X+xh;do)g8e{CBf_?=nQ_SXp`K&t7Cwham6v;jaF&RAE)ZkL1oMfD%w%qZ zh|}P9sma`ZFM0FWgV2F9M+pOWe4J^552(fnml*ve^+9i11z5_mU5vNWBb<(x8gs766nQZ;)8sE-7$ zai>X(xc{{861LM^kAr3fA?%7S+g~IUvj!jE31J23>`VK0;**p+#v5-B_M>o*G^*&< zn5?{6@oo}r!1SLp-vUQ6|1R-Z7@>O;#Zl!&PT`G-X_vDcqGZl_mMc=y!S1-O2J&5t z>1+P{r{t$&{VwNV^qBh0%u;1tLE$b!A7Yb1V}@zdJBz(k(@^ONeSQ}-bv;Ua4L#9D z@>(Vuc4tm_3qenY=pk?{haWi^hR&InGIOWZS4s%k&)T_2x>3NvaEV@q+Z*3;@dD!G z>*(lt$*X6C{X#ujRkn5fHuz@tTy7I!%=!96icYR{W*PHh>lWgH{n}uuyGs6ICV_Fj zOP+hbJQbFd$|DH7$k1Wly1TK7z}eaGI@@jN2cBPMUVmEUJMojM{Zv_7zZvi?MSF1H z{}kH?{*`bEu{L=1(O&hOdUh(&e~vUvb}YsN$Gnu&$Y>8_hyQeX1GomGBHOfg7~tI8 zZLCXp%Cz>b5}Cr`n+76df~vUwq}%bEpz+#Qjv|<4k{#!wQyu_9Qbk*NOmh4IO#pUP z)ATU!wROsN5h}jKOG@`2HA4?>=wHx|T3bY~s<~<2jtcmG3gpu_rNx)W4i`tL{n>lgGWLaE;S@er`33qAHgZ1`T=VIcGGr% zdDBkLf;Vjw_vWvU-yn3dBcbejOq0=?L^A%Gf6&9;f7P$LU~a|TBY}E~`<#3N%i2}T z4Jfbp^|o$ak`fd!w&{3n-kxv_9JD0h+?i2%Okt@LIX@y{6PA{}Jw4#=e|9w}+oxBj zd9=DBD{PD*u86j^e90bIHRQN*qM*mMrf`+JClo%lizxXaR_+Kp)a@_y?t5vwf>V~` zyPoBg03M3!zFQ2S(17zCpHg^7RIHLH@Mn6(NXm}6+_jE*z9RqEF&>!GgruWhd!3Ix zDy6-2PQt%y1=m^dILVcaneFEg8SxJ2)wRGa*jyhsMkNsaD;zpP%m1e>5b2C9ezLY8 zrU8bbvFWk2Hb|??^5B*oGt=m@xDl(_7z)f=GXL}JEB+N8fLn}RVOK)oY5ki{l$-Sa z6W#-o0%L*!_~FOBc3en-rIz>eDy;#^p8*q4G^heTU)SQP9TNLcbsF>oeI>zy;n? z;_1v}VaH1#K!dVZaM3ump=HtRe&-W8A1n=LA~NiH#8UX)T+Vhd!VbMz`UrP(WR`4h1VU)obf-gCL|e)G zQ-+g%;CJQ89@@ds1IrZ`9*#s!U=0UZtlZc*9N42=U|S^*4X0O2d-WHIceG+DMahBw zSnlzb-C1VZ16#0>XanyF^#`g6D8xi}&Ol&+OsORzvT|IfxOI$H z6%(DPc}}oN+GaV^X}ZICft9*cUnl80I@V^;-8%X*<;xFZ z4)v=yTP6I@AC zqqze(ttY&-egu4MWCaE^T-?x1P1w0qAgjPaA(derIY7Sh@(9R?#MxZzWY=>c41uLO zKb`JhFx`=+1mpsTj3I}Us5ZC9#)S(}cdSahMZ*zXXu#%|sId%}~~ zNn1bZeXO3~Ngua+_Ntvren&ri{>C-7RErv<8F(56Bve_?xR<1-nr`4?U(G0=m=nWY zxG@rs#^(N}-!S)RVRLL7Fzj4^3wzYLs3zB^d{Qv5`$D72)^hqbvkQHN2uzAD!M5+#&X?ib9E{v`lfI1VRjePE zUzq&gEP%qnnnwFhPSq51=w3iuXr&~F5YVZ}vbmN7y=msvV#FTmRjyMXV@-cJ^ z&KFOWqclndyuu_HhIQT8e@1`(Mf0>FF>TbUC(V(8!3A#(K-w!hjIZu6KyQT^nJH#gE^SAyVrXU!0TTLXS$p6^`eC z$9P-$NazguYVgaHGqR?E*uoB?YVE(962Bu3JlS7w9(iZ;Z80{{h6dv@)8TH?8R|0> zHFeJ%e7SA*Xtz5O%@v)hxA)_ z{cpp4Uw=x*xxcn3ei`#jqL<|!y;v5^;kcL^R&wG3HarutAK66twH__haFq}GYJ(LH zyLAtXiQ@83lwV58Oro#3KLMzG@uWJIUAt1D%>X-IyqAM3Cf^1h?VG(sGQ={5)8jLJ zB{;rf%rY*~RgNx0636kOA=nBMa!w^Hs`-iAsy=*^L zdm^VGF-w2u`<|qM2S+4i%J7xkBfde!xzk&{iTFf?6GuEv+DTtn1f8OhTI(u@pOG2;`u(fa6$cd001&BpMId=q2 znIoMqwY^P{H75qDXtID~Rk*9U?ej^fA5Q#El+>j43PdJ|Qx=v1P;_x?^OuD5-06#w zLus+_1YYHrSNBhJSyuG5OQ6}9Vs6n9(s4!P=QP`25+M|vgo=}B;ILVZ-CMmWo9E;T z=h$3FOQL{BDhV-vzviL2tQw1j5k`{>Ty{NzqqmDSMoyKTAtymMWhggAT8^4NnB1$CT^zD} zIrqdketl{61rE!pQ1a5$6Gzs$Los1wzs>afSlU?{99@i{c{Fbpw^cDWf1#2?sInDI zbSh|2NUFfwcjj%2 z9(rmXtQCfAt60QuyyrjDU3Qp11VHMed`rm>laIxF3Ij+gt2qCn+Ln8#Fne0pF!nMo zXMS5ozx8^2;31(+>h@K&o7H+FL8Ght_kHHh9{zAk#9!JO9?V{Z82a9GR?jqcWVevz zU-2y7pgF*21t8YZ)q%J?b5 zLP=khai@Lkaf|yRhN7?;W8FIb)#!S!=W};{wzmsL*rmK0?|r8a{H^X8!_34e4->*Y zv~A(B(A~qyIv+nD#h4G16bWhp3yp)K3IRcvX*=O8JF3Np6_kX zs6TnO@{^4}?T($U$X=&0fmZJnVAblh4l3-C-%=7X2``-6Av-$(JR=XUP zSj(A~y|Rhn>R<7`y!`k9gK|vPx1J;36^f`h)7IWuZfqVZc^*im18`$f z@=8X#d-}pNWWT|dsNUNnxilaAiU}RwVZQ%w@*lL)45hl^^0%%zBUQO}*86x4oDy?NnOO$0`Pp4D0HcZgX7~}MQhgE~+ z$8y&m!kn$(&CAn)gKp`4s_DJIi!w7O1}J{yq(1sfD;*=syQuE0h~aqU^)?=22>s7c zrri)5abcT9$ck>%pJql;nne?=bB1qE+sNhJO@i~De)UjFTY!&Vw*Kex1{Q`vLy2+C zlRJ+k(r$lOi8=?w{!~YeglCwbHQlSH;x(Df`BylpO!~PqM6*s*uT7%prtnCk zN+n9d6IYd}M;M#=G(&w;lTTE(IF2t$JLW%v#rugztsZbD$MO1Xy2D^%FQ&I=H>mFl z6>SggGZ-i2c|zhJ-&BX}H11Dx^R0>DUdHC7mtatq{xboCF+5V{rzuJ04O9Dj^)ztn z^yi2Z=v1>S#ea05r{s*R%u=^wGuYT1o5a zsN{y2Gp3po^^P@COTHmyI11d2!BX`@->J$FNJp$ACP7FPOLU$7k)Q79b}l1o2v=N^ zJ8C!|=FC-IRigADe-8Z<@ECu2y-yD+-N8JrTMF^L)qi)SxNFakgsb{?#qGxLmTz0k z5o-;}y&cM7y8}^Kv!6gt|G<^xIsi}N_BXe!F@b9za6gHr6~&Fg&m;c*YMl7)?(;=@$%+QC1=dd)DJ zJ}=gU9bQMGtlM2_+%Vz+pYoEtrhG|`WBqP?lB>Y@#~EW&%yTtH!q8i6V39XYr@GMZ z7R*$~PAU3){ZFhyN6(Mh@EQa?-DB$6N9k>zV&L>A+NxzVT}%~{BA6AGvax)DTfgH* z)IJ~gTKTsMjQcx-ZW0Coit-t-d`*sg+I6PlJu}I2VnK;7&XAsd^+SHRUs$E87!D1g zW*91-dT=edHk&oq4Mj#D|F^7Mb+E7#g*-!VZso;Y4D z;hRS%2NiQ)cPPJ$xr8Uw&2WNS%zA0Ue=%i$YzBEzA!N;Hz(Ke&rKiJzWz2VeCj2|7 zB}w^L`IVZ=ke2VwMEdV)0~;#;D+FQijBOSuYw(?lr*V`oaO_i`N50Zx2`%13r4iLu z7u1fh+}jw$mSl%t_~wlhTo6r_EZ*=d2T-lXkESQ@CH2yaFJRqb>>)jcQ$@vA)stnB zb;Rha7lOeRYl+Y!)vw_D)>d_bJSD79?x%~Y^$Wv{41*Zs8yB~j#*llaVU~*GRuo(i zG<%_F99TRp1;2%pg?Z*n*pov!!`S@_$2poh9R=ztN1WO5)Toa8o7r=KsGh|E+5fhX zR|*M|87v$1!Z?jnft#!D8)rv*jd%2g6h1QgoT?Yr4*Ot){pkV}_(={It20Bq{~6FK z?kd;uTQD3pKKns+Fa5I814eS*KsGq}G#12%=fctMP-h6l`$rX|5JM8^-^3t}R*F1+ z#tDUb1T1WAu6&wf9%Ea~hcTAl9|C0p?QeQe3kp#|8J0Io;uR>am+`rRoHT!Jn^4P= zP^h!DzvE8>p9PnCn$s?DZNkpY8U~5e@W^Fv)^Y&jDnzYz-e^D`ZeK5LdV_;M_Urlj zmu5Q=Z{fI(X3L+EeGBtQb4JNu&e>BHOqD29`W6@Ag655m0oe^IQ5B2!Zw3c_9*h)L ztHYcfMpj0jRsve>P_QQIEClI+Su)~lKR7c`cE{t%J{J0h&~Hod{#5~|Uu8~=(d2+$ zM#HQZA+qN#9T)F~xMy9i`&|HgB8zL(FyMOW*3A=+w)Lx~-N+B$t&j+0sR1FDrG0~o zQ_F!Yzpy`8)!$jvUw{jZ{5~#L;U_hFnahcPa8#p4LQ5LnmZYcJBF&L{>-iUEsKc#} zFk~S`Snot8iK62D{?ZweH56I2?{YaTAc5|FntjPiI}6&!pw1_VN}^>N*z!i-EMy6d zT?kXgmw!N88Lf=OK10-E3p-agtJakMXA9+~y&J6p{dc#gmZAA70z!Gb?qM-gxmYYd`ofT1Z>OEn>K+mNh*4%%17Nwcbn_Ka+gzA*pOdNCe0e- zKI)M6ciXvNCpeE2ug*(8zNuvb0zhK45O%r;J`~>>Ekdw}uhvfp zs&LXrA*paHH6~*mB)d^u9wh}@?rJ6H@N-BTy*L8wuKjj^W~a%R6Oe1*Zp|6{!cm!s zN)*a-S?suMODdqaZ(Oc`yw3i>VwOy+IkgHRX60)C{pnZzf2J7Q-DMl~4y5r>5B!2R z8xl{q2ZG@A0jui8+$Oj6RJdkOPdnJ4SfKyQ$#Qe8~f17I|(0N4n z4NW1=?Z~;s*Qmi1jbP5rTN1TuX7=Y0se%$dm*nJP4SjoO|IHJ&c*?Gj5*SrY!R1cC zW7qsahef6l&=TQC+it<+x7*c)J3&Ev9^?A4*$d@BUFz1*OhTf_kg#1JaPjnlH~ODu z#RbA#jC`4A_Z#8_H;=fQ1;h&+*Hg?}es(*gghR>?Za5#E98rBgVc#2@A+pZU1>fkS z&OJ>`NuvdOg1oF5}&R-U@h=UTkCO^$v?GlD9txHU5lm0 zz@SOtFn33R-h3UOA&z`LG`GBy)FF3*>NI9^#~)*{ny{H-#6UlAXN5Qm9>aDD%=D9D*` zr>5=CVNydcxq#bY+4)Oh0L1Gyz*r|Qv7Cq-Y4*s49fg;H&QL ziL7@)pQKdDsW=%~KodG@w`_caPnEga1m4~D|G8BRvI9C5|7YMt?HUaW+HS_|PsL|u zAL!;o8PE8&9-_i_D@KcHHyA#{ptCdxb1|rNup2ZmAJ=!cE|BQjQYA=&qjD!LlLWr- z-3JkDZ=HY8j38Ic;($8FTRCkEq{ zv_BG$Ft1pty+mq~{4Hjjwb4EohpVOwCInp54FMr{xL8(!{8Z)y@^Sy^ak5hoC<7HMLNaX1n%a*%7q;b-G#1`FHkf zpGz*m2%0&Cge%(LU4XJ<4&H41m7-Ct5`Tt7H@$yT@VkZRk*yT(qTTv}JvSy_zP_E7WqV}#Dt*$apocX zi2X-pa?c2g1}Z!Y*SrW%uIW`*`EEgnr>Kc)*yam0aY^2X(L~(AK&J~#kSc|)HT2gi z)wGmsmmP9k&F1<-Y=LVB-Ji>xT$Qb5 zQuuS@%9v^~kza$Qv#nAx-B?@W0no|x@^%m6)*)hcIxv$>L3k%}o8L{)$y}%19W0Q?%ps}NUPD6CWD?fm}QlY8o7QZ@LYr>fmE>3Lgn)Bag};BG!n>q1RMBy=au5`hg_zf$+vR~E-SSpRI1N&9<% z<*_pddP|caFqrE?;A&OpJD#ADzjc}EO#=s;cj`3B_d&w)voU0=fW{cX2%{u-!U^62;wdZoVRhl{0!eo_v7B?n&g0PO|%-vdb7$2&o9Dj*i}KDI`B1Rzql zQzgdvF~WqB<_ma+7;N0hsr-{Z%<0QezIOz~fJL|>F)PyH`ZKZ^EP=(4c+Z1&^DK~= zhfJj)i}K~$uF>O%ze0Y*I>#AnSv1PMM->)*r_vszWW%n-OSm{~E)Q6@2$V&&N#xaV zq)Q0);|vD&l_G!%u3`Ns%Z*aIck^cS*zx3p64fB;_rQ^vq}`l5VbDBO?mxJCowIBs z8r-A3aL#!fzE+bv1Io1&eUr!|DToBrwePC4!0WiN--%(LFPRWd)sB`U0?>}lv~wo+ zlumPYlCTr2YWu3S(kj23ZRVH<^RIAXlT*G#`g`q1ks_sd{{#hc;^%!=qbHf3zODMC z0IVas*D%ms!L37%YC0$(<5Zg^qB@o2Kf_&LF0sv91EbMoDd@@(BDgqwlT(pX1Jydm zBa|(sEicuLmV=PM@6QfD0dqrcMZsxifVMC*nEDHUv5g8bnZ?)_^T$?2sqWjdFUMQ= zD7*ZFVfJ2o^&8J{su{|*M;DiJqX#|B0-AD^MGd?mSQ%azKE5VZ(T6v&s`n}V##$RO z(pKQrUB=TQDqemEXs5arwAV9g{Z!(yLBeugtRCqB;Y3-89q;_ADK{O4?aF#Y^~Esf z4z8jP+ft{j>t zgu0i^MYr0%ubZO@>nEs&NO^J8vmkg|>g0B}ENx~-a@koz?L)>(6lpL_&SQt<`sze) z_L4$<(u39pj3Unh;$B$r+0Y+S+kz~`;ZGXH`J5m-ADN7yfCLI2mr;2;ewb`^ewL1L z_T=|mI;02N0%6Ra+^xvgDKvMG_SuGQ_NJVi5?8`R8>>ZKeN=g0{k0Z9SnHAQ6SVfBf#JIVJ(2J;jM@67t*UW8=cGKtjVr$V z^JC)dSXO}rooc)te=RI(J<;Uj@|K!n`vhz2R5uUd8o|c&PjF3+D!rrNU!{PfQ#Z-= z@!LUYQD~3zOiZ;!kf25Mr(d-b+@$uy+ci-Kneo_#kF@kL*JC!VBI{3*ICihVHT_?9 z*$UTZ!e;sV`z(?gsDAF+OO2pmLotv>HKZBG8=olOoH_NmJ|Q~u(#a&{NuJt7mfZC1 z+MoxZJGcd5#ZSa$$NhE7)=wUNA^H`xMYDgoF3FSu;q&AoB}V067udaKTjaTvS5^DX zn~t96fHCW{dSO27H-Gu-iOk-p-6(^-_1=?ykd5nLkOZZbPV9XfQ2stI|BEOmqB|NNjO(| zw2Y>wk0L~gai)nLSV%tRVmJvI)o)?#N)j;X)`0#0$QG=3F6D?`KA){1-7O-aSp-o- zw?WT4pA>j2cY!$m&r8d|$V(c~rGb2qxoL$9*b#pjvc)6UMVgRihvQT`y*$pzgvFhA z4QRS)K%g_kIy6STN>|CqHbUQV;41!XEaHl}Wrfoz ztLYLS=t<*yI#wHSH>l26(xEM7BM2D`;7lGMW;2G$DGogafYRclmuY#|?D9 z9THtL6yztQMb18BYW?uGo)Kop15z{pvb^_x7)FZMGtK+gu?sj)8E!0eDkWE(ze*J) z;1BYzXhdH>U&HmwXkV3`PtzBYi`(&7P?YM zN&AxX$=^9PqRxiCwdb*m6IJh(m6%XJn3hs@s{uAOnsMcRr!2CMjSq0Ny5^C46j@(6 z5uD^U|Nd-T{N8vR8qM1HW}OvYKCFTdILG2zVn?-tzHk{}ecjZ^4%LGX)HTfek^QF8 zb%CPjUocZUn{lKn%hR|xI~u@|jJ*Au5x4x%o|hL4t!>ZOD4o;PQ{$sqPH#`{ouxkE zGBv`ogXl@CfZNKo)LB>7p6E>NN}qF=+`E7DU49@tlv(`ADE2%dd&67XS2l zWClv9Cbk?o))3Bq)Q`1OD?>vk-F3YZaq+%?`agPff4Vp;@hoUB3Ut0uH;wzq-ja)F7e`m*n*u0*azjRGQE~YAO zzvX-lOUC|6{WSxn5)}(sy%O7_3hLvhzqcw{jHVYX5|#c*=+G=;dMV_Bn$Fe(mfo0P z(&T4hxpWg%&=fziGA9>tb`}31D?vC7;&LcMbC?@qwY<;0_lR8rYnOe>dYUS|zRLbb zyk>Esx`Q#@Gxo4sACcf)t7rhU)X1knC` zO26J`iEJw@4&wasxD;ytw(wZK>gz^ZEHlkT^7$8G(d5g8EK23Ubl+Co0&5@Iyh{-?{8lo8+N4<{98#!*dk zVLY)oU|r3`?9Wr_q!@@4uhFmwdGY)qJ?)158AQ<|*S)C69yXG5jamy)t;tif)bP(y ziB=3e4sqmyNrr{T!uYKfo-FQar>XSp3F?*c2mFRO*Rgw9^kffi zSrf}Y4d#m|430}{-2d_1&kMAq=7Uhb>tB-7&d%MYCz0?RNA0ELF zR|qZs%~R#~vGp`_lN>h|PJ+6Y>(bmhwFtt;LFU(|&_3ZIY7ea7V;{BnB|R_sJmt%MXsn)JUrmTcfVH32u+^3qS4l zI=EGpOtw#Io`(_G@0x*NN)7XcoI@C(@O@N-;5KuF`;$k*&k<1@?W`5X+v|by?Isp2 z^az{1N~I2an?e4x_C=GvQrI`*E|t4bjS~v|-)Q6SABns=;L z0*dZO)$PO8G8SZoNDD>VdD_l)@{GpgAOm3hhMR8$GigXrlAR}e0yu8Z@B887!oA?`CHJh;9+Y~RSvliGGSsd1WOLBLA|Hkp1jp0Ak| zVR;`Lz1d!L2b+y-CAVv(h?1)C$;!6Fri?Ldua_4Ji#z^T5rqcXwj?%Tugi9#NLi1u zzFSjISES&$7+;ynQzr2BE1Hee*KaQt#XL)1W%>)HONvdjCHj1r$fzM5b}gPS!81bmh_iyk+%Y3IH!E z=#n_WfDcI;Uz%cYRp>Lu!h2})Yb8crg2?DuMCy7Ja69Q3pF@Ofm`LNr+7EvIbam#M z2u3D!oSQ)n@6B!7)g%funo^UIBN5&elbe4pvK_S~lpE!VB)#4Nc%2l5RAlVuIw*Q< zOLO8S#cM_b-R7G=)dgR@s@X_%YX|K3OIynXd==3I7($GaZ+Y(1lGTD^Z1G=zCeisN zSLqRcNXq>7fphVNr2(@3i1%jcLH-|71Rx#Rsj|nRJb3It*`$2?R2oEzl$tjm%!-Fn zQBeq_3+GUSl{luD`=#Leo&r5pTZe9c4%+nhawOzco$Hxo4U1(@E?V|+FI&zjO?@A6 zB>p?L?!J8X9Nl+0_+GRVxccuP&(N-j-sbR8Bk;ZoA$wFwHEBg|aGbC4zJiWgHqPX% zcGtaGF>_$DzUa2Oz*rMCL6eDn*n?!X=V+ZOTtmdzfr^ zFoct<>JF}9x)Bn+utL|{8)nU+SEsWQw&>SSEsvy(nfl0eb6)+~Ijzc1O|}~%Cut(l zs9b9>KO^hiTMZeGp&U0&e@R`YwLo0UodjcN_s=y=2Y&glHWDr5bH9Pda$O1>)p8Gq zEsu(!m0ZmYzV48*@uj*^N-FR-PH)rVm4=5cjiAjM(j#F#b4Nrt7j7gduWzZ2{+Fj# zXJ7vX4*0Bvg@tS{HPW+0Kn%XlNS;JQ#4h7ij*sL}Qt$d9;DLMjAnF^P?S6FHz|tGojwCESci{$L3G=`cuKH!#&+y_T#Gu|REoS*45-Uems|z1&{uu|ew7s$ zXVR69eSE^);OZpc^}H_dJ6+{e2FM=mvYyk0t(^RQ#>r3G#ivBTuW^HcEYgECRu?;% z$;o2~eF4&%2AV;yWnYO=g(hwe!B;2jHC)|gwn_iq-jbMAcP4wJB_HU~;&bx;03g^n z2HHM{^wH!bp{p-jEi;|G8OVMst5rTf6Gk1~2nI3HKNXy1ve^mrlhkD+!LNwVq`W}# zZRJ*;iv4w?L_8>}w0NNc!`bAw8GzFU)pvtl?ia(oSE?!N>fInsrtb%HD3Ax1LD`); zSXl3IKAzwLTTGwxR3#y^1|xMth!c;htUd<#4JB=p!yRru zJ0on`%-+Z=9tfU40SUTKzF!>)yR%s5f~O^)BAPeXc%JW@t^l87!(!`d3ZS(G?;Yl$ zy=DP1$5xJz0%e-n(;iG1+pkGszBTQ=)RKrJ8_eYq=JOUhjYk#C7v^U={1#hzZwiaX?J%7yh_Q0i5(tHUZnpcJT>V(qH((f zSkY`vf4D0F1wR>&$~%O1r7+FqokN&^oo8kY$1lRjMLlyx8!ApjmNPI2dnG%ZLdOK` zzJ(AKv8j*sv8&C^o$9Ep(cB#!XxSHOutyH?h%^)BFuw)Cd}s!zXLzpeN(!Ne!w5md zC1k4l(qK`ByQ}XBn2?YrG7AU8Jz_xU%*mV2abPr;T_JxD>okrXgSN4piM?%ivIdmw z=K+~K#Ty?#<&2qFX9`}ak+7s^ZyWz_JQN=Z{!7Lni4%p6Kc8m>FL*iN z6qk{hP19!yipsYGKX-ZlH>}Hi_wo$$Jl~mvbK_88B~YIIfjO02yj30zxqO30RDm2= zZCV5}g<1V}1jKCQ+W$8@jF%R%`O7&%R`rYEcl|A^F4jyV74}A<;H?_oxd`Opqqbx? zeYBJ3hDjf{^VqTWUcZ6vl3=S_Ux$3>`orc%349AzlhP9Gc5cfd<>bLdg#*R2GGHhk Om7%V&PT6gT=l>5bzSk50 diff --git a/doc/pics/qtgui.png b/doc/pics/qtgui.png deleted file mode 100644 index 6815d56d9e674122fb790ea93986e34e8ef6e68b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 379842 zcmdSAby!sY+CHjMl1fUWBAr7sD2g;gNw?t84KsAfARwv007G{-(kV4aNSCDa00L4{ zf@k4(@BO}K|IT&J-{+6H=9*#FTF>X{`+gq6)K%q)31|s!-MU4rs34

    lQZr)~!2* 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

    dER13vd$@A`)R3TNDX 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⋘{mf=;Kd@Px2#FFUN|Xq6UK{8TNdi+bC64aqQ0rJo>dGFBqz2`)L$Kd6|b@vH}Ixi9dn>+WP z;_*A|J&!-)-Z%o}5snSZt!{I8LxGa%+!X4N3|=~SxMz;wv11B#ref`k-{xDX4^f;Q zBhZ=dp+hi-YwRvxmPJ5ESej*syJG-4R|c=5XJ8zc2^WZiVZ*~ zt&D(YsSLuxiU4-6?-bB6#L@9U*fOng*_8|Y z(w+EjSDuLu&jB4_*%f)|$n?e~RbIBnU9X;(5JP7=(2@EZmt6%(pkn1Y1R8*jg1tjd z%a%f&5Ebl$(%2N#F5QUh>o4Mi-J|%;f&2K)-beVw_B(jGeiCRxr{`)^b9%o??Ew>^Mop@^~lWZVQX2|J@*tJ9(;tS+X?2}#M|qy z@vX%_+;j);Z@P^Sw%o>tJMOaUH}QDu1m4*;fhRjA@Nh#PCJHWMVDV`TFFA|rE1U4R zd;lM9y@8L|v+u0CiMNWc<9^XNuI655-?ttkSr>6Fy8+i1)#B=c^SGT!`;8^bw92h=|eOFIl_qAi#Ie8d+uCl!A$8hMzQ5?E< z2nQzjW6xL>b`EXD#=Z)y>ng#T#v&A-DMZ=f;;G4iXrhTGnrL4>`(gu~-*a&DF{tyd z0q8t=Vu0>^?#>fP+ns>SL%~>h zC;|%!)EtatX%w;!$71o3cq};_hs6hDkaZv$i}tf?`@)gAHw0-_fk@pMfYj{)NZS^O zlr8>9-lW5Vjow&L>5ZffUR(<*ypd4miI`$7B38N~B+m_jOI_iU=?M1)O1Q9zzC*YT zR3U5)eo0rp2OicPw7- zfu$8*$lc(B+)4_L?2qgX{>ZBEM@G3HQr7B_RO~YabfT6Eadcb_fsxal;4=kuRM60p zA|udI1=vAJ%dUJSkm;Cwn7k!CNHT{zM%j5Y>1CODQW%$6so)WzhFg@1eK!Rh;$=`SkV2JY2m1sGJGX&-98(O5oyXe2 zk%?0KXbIkQ`T_sLj68It!SkVtwPLb_lBLSH=Yfta%^ddG7Vs>VB5a!jGLLzns4)mz zdSY;JG!^G=WTWA30oop{M&DayxcYV_CZBA?&_|mw{M(%vdv6EoYO}CA-v`wNahN=? z1^4S}@OEb(9<+{NU|%~ft*yn-x)zL;wqa;Z8!i_#;tK1x@!}rbSwCt3I_t)9y<`M8 z%GmLy8@RjuChqLGj_cdTIMDgv6agLb(0PETTW{m7va5JlJcf7IUBw3#*YRHYRlK*J zY2!6KE+4_YwS9QFegN-m8p4BhmvJ@!BKk57V0} zrWAJ~YVjbt9uLX$Ci((yN1VlV^2`Z2j>&+-81vbSQO_!jc|yuajH$uR zSf=<|++gKT#@Fxw$Rlwz7*8~UorH_H7F&nwQMF7L__HHHC(##p4Bdf8&>nmUO~Lz6 z7f^)@fjdwguoY+gDsW0)f)oC$aoE2Ad;M~-J1_@3Lzkc;E)C^58Q8wH5C_g}!J*DQ z*fX#XTZVU|a e$97`t_)hF#>8_FOs2XA#+=iV4Td<|K0%biVDD28dPQzj>J+%mV z2bYOJM>Nqy6YWcEuLE=p5as3iT!4;I!j4=s0-d*h&4CVWh5qQ_uMEdVX!91qoOeDB zbolvOKj+J?1TP*s7w$1#j`a-ayoWmv-Z#eIG3f4t_c+WUsB`t^BMxc|z{VgU)(#J% zeA^IzN64Sa@0@rnv>x4Na(NpcpzWMxfJzqsLDoAt?pl z`sV)?fzE51$PYxIBLbZ{0y;T6jw5kP3>NIvGX-%a?+QjrRVdQ-L?UBv6f*ZQ?PbS% zB9Oj23~5y%NZl2P)b0LA+3JgwEq+MZ?1u##^+?>{jf4%JNT~2c{CamL4sRPLZ~-53zwN&>C`I3)p$jhpqdYkhsr-+{*&?zE*G! zvVk^I0v`eBEL9;QUybNO^3ZWa!fGchD0V?=sRrq5-LP<-7K_TycHiM`oEGX=_<~i*-mS@PSB+}z$?Wb9*JtW#j4=K zce+xry2@BxrH0_hwDd}E$Dxi?XUoBk)W`OjSe{h>JkYW8wSF!zvMSIH_N+WAR}mqH zjJ=2A>39dYATulsyVDEMzG5%NS6Acu%8M9Xasj=mr_hyf6s@rb&=|7^&C$Eiowy$Z znI|x`M_2u4cAMqa5&Msq7B^z&FEg)h)b(#(Oz^89VO?`S#}1e^0r}l%mVoP zy1-R0g=?T3F07r7tS*jGa_*_)8l~hwhcC5?Qo}Vy3FlaYXO1$-2z25laEP;kLo5>k zooHK@vb-2OI5OEs*y3-#{@45uv;Q#vXV|m*Na{FisF;)qR!}5bL$SabvJ^|m)66)~ z@mMWE$YwQC4{4EK)cs9Z0W|Gi+$*?YC=z0Ek-L^Fubk>{Uwd)Dy&8CnkHPW z=*8^~L%6$s6nD$UaHC`xSD9{6 zJdOwXeR#B@AMX?m;oVh(c(;hDco>gX_v2n+H}0>wgomZwxVO3k*YoQ!kZ~MW682*> z`55jkZNPhL`q}-XxRW=4YuQ(DeOVu_=3K_W!g_S4oIzj4S&T2P!9?15j6@&DweV9s zCeGv34!oUl2}^8ac|ZTn*Zvx90ef&ewvI!eJ8>6qGwK|!v-__F9mS*{dFSlLsOK&Y zbw+&;VIuehyM6{YqR-<-Of_!C*Wh|WEhZCcFdA2lA*PY|3m9V>kFCZ;R5f36H5pNj zt4yO|r_mpD43~qB;8Mt8v<2@+Q{Zk~B%tHJ8Rz^faK>*fPWr9J3BOf1qRYcxk0q$` z$-M6zM%ca=Vy%rlU ztwnjq8Wgp!KyGt37S^O9jP=^Oie#FwZeuYPG89Z~|dgoVM4+151#y#d+Z27m4#~tu=9Le zoo7Jj{&OBY+-rxR50@e6@pL^GM`!FVMhN;C^9PMfu=<8?pocHFGU#&uB)aBs*;V_M zVYFVR9k2SCdePW<8TB3AsB7&)O>+lo8r#_%uN@bg+fdukjQYk_96f#t35lur*8ll7 z{`imn82*WiM4&TE6ZwG%bVQ&t2SBHPcm&I~A4Bx|a71tLK+Fc6L6v@p+Z2Grtsz*j zEfmSyLy^Liye)(&h$#RIw)!D?vmOgbn{-I3)FFXjPK5{JE8Mx_)@u=4u0_l`Eh5)w z5W3O{fw>OwU2G4p3>DlL$l)4m2j_4*I0Q+c_OpT9#}alPX0X-HgG4(Ya!(7Wbyjc+ zw1QiNExZ$@2w12<=rT1TctB*@vfK%YOv$TVkXE8WdZ`;SOWm<>tp~Db$Ez}LEL!J< zh3kBfxmJgaQXNu@S)Ge~5Vyh;G5H>d%yUOrt{Z~0T@aAv1m8?Y_@vpxGg%Gy1Qj%~ zDmX_e;TW!fI#do-undX-DP+EOkm@BI+VGvMrqbtkwt5cen8wi|Pah_AkS#0M2FeI_ z9<78rObtzd6JkRHQIWC~=d&x(l~skF#42<}>_BVqb~J_VL_=g1E=KQS>2`F*?M8pv zQ4BAs#${z=RX4f|JJ40sjIOm8(Yo#&nk!G?eAynXP0vP%uNF=^ zR*yg%sDo``A0~l4`!4p8?At_1;S??BORij^6>#A&M**ie1soFOP$x)X&*Vrkc47^3 zq-9#C#O=-fxV?T5cgja_vt$rgSNG#u=>Tr7AI9yCEN{~=u5ReZ+XwFA7subllgg|3 zaNPu+77pS5l1|*rXvXb@Ex4D}h6hX9@m6j(-dWj;$15)5eqI}HEpNo_{3hI3ei6f& z$I%;Ah2ii$xRZJo?-X=#0Cac70LGVeV`9l=Twi_#qf6V+yQmJmi)%2vv=-xwE?^?z z6mEte#l5gocpO)UcT!s5_-{5-e*}N)Z~hUNB934(u?E)?YH&UFJg!C1a;u}5@ZFDb zuPTgt>|$c6&wfn$9me(GMX`0jEX#q;fT{12s?qEkfXR1di*U?4 zABWtRVXwzxZ1c&$I(;1S{KK#;J_?0J87Mzghz*UUSl3pB;?4q;bmn1gM@+rtTbpsy zt&O|8yA*eq;!+%1q&UHfyF>Ay!Ci_JX|dqJ-HKC+yQX+?=gs}R`+oNRl7ArAF~6BL z=UT(P(6VpAbvnA3A1{R6W@yw(Bt}ZYc`AGCh3D>@SN-$ybi0AvTc`(O1f@lyFJl&JS=>{g<4toa=x{ z34|v4Y|poC)F4ccxff+xa3}7)ceoIe_bA|Sd-oe9;IHI`PCxIFdS0Z zg5#vZ)t3)&;^lp5-y$Ro#yEi2TWvC<0(}MeKEcl`jNIb1xt~Gam|X*MR0WPyM-x&r z>GQ3i)owCD#f+&K1u43FaZN&>zc>0=r$ZPU=Mgc{_o{E? zlzxa9e2&G{h2^yMvAZ%=U&uLivzBCbFiI|B)5AJ3$P#)8=4r87E6^a0;!Ks@o-lo8 zkR7Is$-zHqBY*7kc!yw<{J7i)3TMnau@Fj=ZrO`d)pS0P0cM&SHS%*6quD%c^S_f@ zdP1PaBgYS&yJi;cYNB$+Y~9hFU}-|FR!(z~%A;~s2!{I1E1oF;CN#YU&xiN-L2-`M`LPL86|OMAQ?FoVBZAEiwgZn`_~lurP~bQKrN->9pOX@iqXz=_ie>*a7SFq^0-+mV7HZhMZcN};B@*ORULf^vG1VniCVbs=~^fi~z znDG1^x|uUG;p$G9{bLI0_(F8<)D|rPt2NsVYJQ!O`(+{k{#OL0(rGKs1I}7jv)=Ut z6v%6JDiu474-#wiQl8{U9^-y$9h4wh2fowJ>IzrkM}X`At5Cu)%P z@06{Xjdus$0Hz9J#PK7(WIf>Q5UCs21D1<2?Z^w5(2vZU#C2$K+qLI*aT+--|8A1D z7`QHw*}FkHeMA^cu_&Lk`}0j!{qbbzy8&@6zsCK^A)mKB+rrHZA%w=C0+toaVl@q5 zD9%MJa1R$h@ngz_ot4J%8cw806px@U@2k{cFfXzj9TcWw!dCY z_#7-Y^-$fXT9+Yulme7rv017xO*nP=^3FG2u{e+{^C$u=%7Uhrr3~1=g(V_%Aq{yi z8-8j<mB_cGD#q^uU!ETk6Uc8EiWoTuO4jQlsliC+)basI=c$Uu-#lFl#8AZ%?N9&i zcbE#9w}+S4((K;u7eJO4!s5A3D;>Yc2YX^VP*Mz$iGQ2>uWSWBLrzAmc)P%OVg3Wy zErZ@e%&lH~Vf;h3mz_&)!H>Rk9u@!CD~5fMzI_dq&%`W-`$}g1bB$~ng#t+jgH@t{ zTF!@jJe{2h;+A3bVnq-dw_E5}5JmgY2fy<1?M!RbEHX#YXrlr8Q51(u!+#Co3XV9G ziw|I*5JKT8*WM{-X`&4hw~N+rwQOw3ozty6c4a&cRzc;c(IBB6eY_cW*-Lh8T?5CI zmSO5IL!ZAB&Kn)aPU!OZoD5w`rcA7)f82|`&!CAJ^HrYr;9~Gt!)uu*mQ^#^>KTQ9 z#0tFs{$o3(I#O5%z15G|L?cWy8{sFOSh_6#=yO@}qiVJpws+xbOa3|!9QCKr!7Xw^ zdu$sp_Fl11GV1s?*jF74)Cl4zl>;EamkR!Ufl5H6G>YoK$+t)IXWRzY z=c~oyxD0hf@e|Q7w%F$P%NTJV%dhQd#A}fkW@<7RgQ^%)@6xhBI910H;BGD~V{S#O z!wj+$+L)2qZH0UaO~uI>t6SP_6BE(o=+nO&OVl;WFLRtGpF2o`^L(v5&e2WSR)NDq zc{9ykA}9t0N(LMFf;^kRvs6Ne>7OXpCuNxS&70)wS-M5QlI3k-Wh7C1;Jv*PrL-S-fOoN=zDAl60aYI;@RuCb<*f z+3~T(X3^6Gc=hREvCP)?(T@D- zmCv3(ANW2^WAf*;@B6uI!V^tDgmxTPI?mCOm6zNSDu{SH!l1P+XoHYZ*|M2DUzl)mZDLl<_d4=M653}YG3 z{6$X+BM{G)mx@&f0uITDI-(gjCuxl~%tq0!26u+S47;UK9y$o?pS2MhaEIuwEQscC z73gfV$Wnb!7+pN!N`&tjgSu$L)x6Qzy?|c})Bd;I2pbn&y*{BNU$UndOjd_Z0ehcl zyX0u+I*?eF zv|I9+e5Q@t@2@&n4?!ph{!E<|ReZ4!RlK}NN%R|zmwGX1`#y{heCd2vBX1^-QY0YB zDpOJFn*4+IwClybZEd7j6JQ{6v?`&qx)S{vL2R9#hR|<6l}uN_Kv@Yp_~E z@l`v^B_cjFM#c^lI+e-=+-_XMq!IJE_*D<|1tA7`P!~^oM!#W*Al1$>RK{$9B>Lmm z@pVqZVsw2>N@SNDNFzza=)H)?QaGwd@wcmt96pY+qaxLS?Fc!9uGKOw%-#V}{STQ` zwy12df!dChh)zZG%Q6R+$gz3IP9_r;`}Zu>1skCX0-JcsBbyjg#ljac88Y7(6fH8b z=*Nj9c|Fv_7zqs8Eo6&P#;R-Cs+v{IcB9j+xaK}cW}_YW)k|tI!9WR@GKrF_b-bM8 z=nET)NL#%%s)dcH>h-_XxVnEX)b;zMbl_V>kp=59Aj6eg>V0to8PlPfMOYqR*{qSg zg3M{5Xxhp{*5|I6KpEr8aKjLABqBA?A`nTz&(g>P;g;Jptlfqfs=gk1dx0VNkWnma z5T?|_Wsk8Obx_%54|*TEu*V2B@_;9-l5j8Wq%~N)v$T?@RT91_^7WLc{n%V`XDGpa zA{Lfk&FKd<-7Ye?ura@+)339rVq-(%DL_M?Pw~#U?gH zahbof2foY^Ax2wf={+Hzi3My*O(he|>oC`Qg$bpzO^1RU>dEu7jQboDsl!Do@mj~p z$(7er0yUFL+Tp65vE&qu-?jKCTKM`B;h4sa{8jr~*$qKMW$&-&nDXDLQ0*kBK<_k57o+EGj7D6qHX>Z~ng-KG~fm((O_}bz6OM)WR zh~GSV=2w(flKi3O!8Ed1v6wz+7g+)zZZm!(n;JsYO`gTj0(iHL=hAR_4m)tYvE#G$ z%VA)W*%?wW-R&q#8QtjU&iumksH*toS@ z^u&KMYikv+hOp3~P_o2~hfG1sdG)V%#|_uI+>c($0C?>krt$+zu0K;|(CJoDAxcCJ zh8Wr>qJ*4?$Yh;ke511SvxDgjdffl3DRqH>Q!sQY@ElQVn5Bh3_9K25dRH0lH7izrs=t&EI0RblZQKWjvKn#Yn{Hn_LWSsz(ti- zf-L&cIdUWexAek!}Z<)6DLj{i7Y3v`HSyz0d>2VUB^jX6_1ke5P#|78GsEmc8qhWLS0h%C1oI zPHd*Q_g52g!1>lq5`01J>+GS|7mI{40PXlU9mE0k2wXY?blJF*u3bErbF zF{*)HAS=b^mD%}~Fv5x{1~#$DL3w2p4AESpeygCP8ml( zfG`N=HFLx_^Zmwe7Yy`ct=h^Ne1xf9AgWqEeuzS&;Ac2-_9aRH3~kVvfS=KM)O)5g z7DYZ))T*Bclu+lGFw4Bt0%+>eFK2bbo zVX)L*OCqYUteMR8cUaYNokc?fD&cAXUws8BVxYuKeJhTgFIC^q{QVhJfB7;!S^UaS z&X`Qa`gUYvcXSzLdUkX=1aTy{k4o94J01i@ILGqzc$e?rPFAT7U@w-+ z0*qVyLZbaWPri8+3pCET)jdb@YJ;KRRIj{aMruvtJ<{-7+EAxv4@2cWX~kuH>>~ST^W!`OtA00R-3<0y z-#d_vRaP|4`fypLS{{owz+YYE{wLd-B1vL8%M6=f5TD394zb|%Vi!UXKxPV4cMf_m z6CZ0T7o8OfTo8W-FYKh-;e#Bm+-JB*QP(o9dW11Qxv(uA5X2{fir;x&j!+m-UrIKQ zUf8@14^ZQ!oy9?6^d6}{gI_aA2uJ=_+IUD~Cfinh_Djd4^#?!?-xvXeWd#N@{@?W* zT1n>zB+J67lnntn2G~d7F8%l*P;>>~b^L=~2w7Y!kpQ$QAV>RwjeA-`>l=K2E9`7F ztI~N%Yq_LP`8b-FA5{Tvh0N4ID>m;T*NWKjskvMBz|9hz_h^JN97#e0Lv>tuG&axBl-X=VuQg zrv_t^q2GLPc`1i*pdan1BSzxV97UdA+>qAgKqWx^gf|9jmYdK%r72;EUIcJ+l}+^ zk2dOJF!9+1w@0#k-@&KaO1GECAPi2okU$oh9mic|FNbh+>SbA~TWx=aE443Pqp3+% z7c#86Mf3#`b!9znXUuO!=4W$w!7xD!_W{@=AC;p*WcgpvsN`hvf^i?;5`~M7@P%em zlxs9nnA&%=Nz1e#{UoR)>L7_Iqe~gb4yGyvQ?-XYL*4~*%|DAvxqgS0*@)}5I%IY~CibGlEO|;bJY|$a6><}X{b=gi{tP!Py?$v0oKMMp^2*!F zVJXa1Q=RWzrZ}=pA6DebTEn_%kK^HtM-i3<`dYLjRkn#nAB9GdF-zsZ^#1fy+?=w; zkG4%C&Pv8m+a?re`M?VoF9ljzgUc^oHu|NkhYXwHfhCvxEG>5yLFTy8xaM-JXA~!F z8wqRIQD|6mviqgsgIXx6$wV!(EnrNmbL@tlRAe1V*qTC_+y(VhB+=13^7&bhC1s8+ zyz$3@cdU$~IXGS+bPqhQz@^34qv_&=h5`ifpdZA2`F^QFAJLIKvs1BUlvQO@*g%@) z9QHYi9GI$79WqOt-L+6!Lhni28ehpucl&6RIJS6u}tsmLq%wK16_RWp|+?q*_Jl z5p197Q%EC(IGA9O5wxwe=f0L89_@$^t~95m61R?!~( z5CVe%O^bZ$q{iJ?Xk&JQ#7Ni_-f>oUWg0YIvhNSiyB*Ph0Z@^I-}{x9sstH30q!FX zol=ewv2&~LlOwP&E~?--c#{kBN$^Ld$A?~FZzN%M1nu$**_1Ac%=UJ=<#C!6S@y_b z2|D{?f#*!oKF1V-6)a;&*>Z12BJH7qqv()vAKMfHh>rwDPs6kvg(relQfg?>eTpoS zr+OHU{~6vW-}h)!aG|v2O_0M3;qE_JUjE?KQrCI+UB_W4j{jb#GltjF%?J;Yc(kEJ zbeXY|Jpf4*$+Hl?z+8R*irG*Aj{5S95BlIIfzo?*mOcX7YL+h)qk?9ebhsZcXC9{Q z{qT$^ni}{~_9@%|2US$5E+2i{FWSZ+nz{k2!v=rmFJ+r0k}%-+^}o(#_yQd-TEAq4&UNrQ_O$=KdKHD_0Y~FaJzjJ`_>8J zG@B(15XY6DZK8Wxq?*;oB@dqz^}&yuf7G!a!Ax!MVk%QZb!4yOBSw!6KN6>bTN13} zhksDYZdAuvxAJiv5Ul679~EHzfKq|Rme07Sj*`8L z_cK!55dIS#mtLy;ncdRgxK1ymN`YWy4)~)9$nT6guDt-t%Ig-eoy|K$CreTbCmeYjS39keyI~bV;#Li zJL3Jp0K+8(L#dzaF#@W$JQ9j6Myr#okVZ?l?g&SV-w%d-f28?X?*mf@_q~eJ20^5T z@+nT}ig99lKWvjLrhx$|uo23rKR60ID2^G;q)ui}A9e8DL+R2Cn;)m0@d?a&nWIlT zZ~3xekzRA9h*RZQTPh~pCcd35jZ_hlHj~+g;rk1>*!3SvQ)HcOa4QM*_P%}WJ7qm5 zWNxL5QpY}SlS%Oi%A7xtTrV8LwcP{GVMa}W;IpU_BM2b6^G=B&seTtg#+Xg$fyEex z%7-6-wz$-Md_wV8e?oQ5ww-WN*C#~a1g|#wWT5g52kZW0$z}%vV+bW5O#|@&->Ms1 zEdiJ1@eH|kbYD>o1m6?S_nnfazL1iq18;i+PH7bB%(vk1Kb|7u0N)Y`OI%cmE}avT z*4Hv#<(bX5{mq?(7P8>iPtdCxxw={mgHGR)5j#@CGKrbG)kMn|vxHd>&bJ7NCZBiq za0CuO5Q^q_$Cse|t>18s9Ba5xj>pkl>mJ|4^2jDwret@V9@U-A@4YyJZ)rwz$E+_0 z_oItKO^B4k^|9MVD^f*JoZEaO9ITtM_@;(&E6QR~!H;45y{|GEs>5(2*S&&`S&)x+ zUMm;*4WkcsK5D3O^E(q;Q|yA9Dlbs4nw&Dp*2#&2*oNhQ=cVA3u&F0nX+$yFkn2G1 z0Y0wNN9sb!7cQ-D(l6K>!IzYouRiQC4PWSN2nzIa&OLYv4tF0eJXfT~AtniM)8nBa z`tqqOm{+e(nk5{zbV}9e10`!{oJwYe?{jf1Hl(+;;laPIF43hgLl{8PW|43{3t zOzkC(aK4?gX^>qF=Rj%TFVOhBloJ0_ONzHfvw$qKQlkI(f*FbgWGJ?ID;ix#p~V8d zyMLQZ+QT!sBPdqeAwW$)JU*1EV%K={5$8W!_CYkSvv?UhlK+Y_+@Vw1@KA^~M6Nkh zBP7+?;+r+{lLCh*7(Mk00o_EG$xWjp0G%6M}@tS+o2cPez|zERh-J=~m&dLXD;<$7<|+h8jy+EA)&WWFl$(E;j!U4zrYUWogDAbl72DR|BAP1Te(?v3q$zqip+)pfd-+Ago)wpG;9ij1MXzX@rj~X~J>jw#g1r*;; z=d5ONurr`JMX=b3|B7`R7TBWo% z2SKEa60UNBo9*KnnpWana#lC48$lK;EepYuchM2J0@QtOqx9twCZ)wdUVmbH8AiARNcz23LcFsIFB2I^+R~hNUyGHDrYuHv7qY-*dG@jT*h-FAxDWL-2g=rY zB;0?pdKbhPP{J{TuN&tQj2;~7GP($A?QpGp9VQu!w$vrq&n<_e(P75{QyS zvrU5_EU7s~csWO(eHF<4AJlr&4OVw~(9fJMpbyxKt6KJVKR3ZadM}yB1*}9052Pk~ zAhA}ikg z@D=Op)gv=!WWZm<=afCf=h;r#=h^pXgS0QW2;!wX?+?EGw`kRdPL&V1P0q+h=O?Xy)zQ+W6o_NYjlk!Vo5{OAYG^JJXLLFm_Lp^lDk>i5Jbpum5*<_ z6}LpZS5~UH#*WLvGg!@ZPNfxj*xvXgbYTj`Iu}Isx`YQLr(AUR1^cYR#pZuK%9_CGSAgQGM; zg{mWJET|pOSMk(T5V?xyj0O@lECA14+C*syFXUA^SzXx9YPUrkp6|I?X_dY{e!)7J zw*Y^KM>NixZ8(+msacLJ`;rqBo6)6@(p*6e6ld1j63kz^7bZNdN}?bG zlmS_P_{Gci5x<&qLHS5!$g?3y*KL|wZTdkHjsIn2vfq&gRs2ZwcEeAiTSF`;25XTgeu2fX2Qg6W@!Qd>No^!Pg8APZRJ6R=Nk~1Gc zH%%S|{r+W|YxZw!peep>rt1VSB%Q{w}-NHW0m))nS7v-m~5t2zGw9_7Nl+nY(S3k zvas!8fzFLuE&FYn0_zw?mQUF;1o|#mUe}1l$C^4ryo)FqiAiU2+Ym`h*=LBl;ZH5| zW(iw}XW#n-(Dy#jetpeK{`yogD!5qs%b$-M)p^L~%^9-OiYP?|b=v=eD{+3c8B5>8 zj`eUd7&@Y_Z}3yZF)4(n_VIi~)Nzr{QOg|eI3A2h7AF?hw*-L3m!B@;?(mN@dZV7p zvmPh;yurRLs~4J1${KhH?YhmF&(!|V^wQzFe8hr-ix2ZC#Je$1Rwv%7Lz+MZr^Y1t zGIoR^pVxQb+g^T0QqELSIwNl7>J=RP&unr_J+g0jY?1@j#pohH028Ha%2m!pQ5->* z$$!iqCBZow_t=MFKy!M%@%xh^61L80QS?M@)aOC?eGsJ> z7v25uDcXUx9^fmiv(66yDyY{r<@|<7WD7?G%FT6YR|T$fR*t>eRSS1hi|_7y4yKCw zhXIk-?Y9f}pYh|73{PCoDSxK_DZi(N-Sk@5e4bs51HVBb_euV_vClI9vA^Z$744!3 zp^7`DQoAC4N)Y-utM69iJXD(VF0t{zZG^24Lo+th?L$MTK%Q4e`DfYjy%byQX)j|x z8;VZv>v$UzGfd`-39!xGl1!RC@*)|BsFI;9bwA7TD@pP(C*4((AOba}p+t^*5kP=h zU`c!$_|Xxb+1Z??m*wWf-#H(<(=gck3&Fk3FMO~{RMF5a+L+IlHmg+|X33=~ewSQ4 z*-A-J8EXlqq*1qoTxO~-h{Nlz=7qXXXka)+u062{!>8f0PZ*+Zp^U&_FqK0omb)iW z^+wbD2b8utFZPVTr&yuGBR&`hWTBu_HJE3RVRR8i_*HlfFf6{58he9!%!=;Jc;<>N z#IgEYFG|#0N?(Z?VDOoK%Enc0^)eVbDIFKaT*2E^LV-x^ZT~|u(b<1rB`zThn1q5O z{o&mxhq5bX6wgz4NVVj94(>pfvL52EK+fK1HJ9{+UQKX~CC3fkt)yB;v2JC50t`~J z#Dgz*R|XGN82k7BZF=+H8#wq7)>b95{(y%L=D~t~jY|_`fQf82CFnCoy~E1rH{IT8agiHuFoocC;du8s&Jt-ypKX0G4897~`}!R6!t;uH(sM)job>)l zEyS#1Y)D(1S*gFZI|Et0E}))vWi!!6eRxx)LZJK`5%uVce*7tBZRRo<;G;@}kx zsAtV!(JD(qfXe`+76TB{!3XWYG%%z!DV9dxOzMLUm~^F}y5|&_^?5joa5j7N%Q-UZGV?QukK*l?DMa=Vz@KbZ+GS&#^iOW%S)x3tcvhBh_VCIa zF4P$Bn7fv|^o_)e;+St1N(aX&C(*bBJ6pE1Wy!wyW`FqZ~ z9BQrDb+yHEHOR*N1uVE|qg*`1>D?Uy#gXbCdx&A;WBZlTr`?i&_a#3Zri($xoDPmt zCFKWLi}U}Y1co~sl?wdJF=-d0Fe|i8gFQYRP8amHd5*X*R0OM8pYoeOPhrjsUMqkH^YgAUT zmE}Vdf{D}5<0SPQt`C?#8-N}`-u+Twc#jtbbLAdTK@Iz*$3&Mw^aHHbR_TUt%hC<3Kr)Ep*20{1dEaA2OYWbAU$ph(LUML2i!^#TEZ!Sw{(GSm?#i86;3 zN3>eVaxH-Ap8y-G19en!hqyeL<*vF&ogmYcJWMmSP3MYUD|ckhU%Pw?2qxZk{3yQx{-IgB_8;z@PB#MDfBps1r(^w9)C;- zIkdupz#1M;{Kxe;-tQd4mEA<8WPYMxdOsN_klO-}JqUnDKYRj7Pz$E2tbnCTp zB<3e#XX^NwvUM6-35SY=#I}WRg_y;AOG!L6>>v5Z4#mqpTsbYizYop<-haYEK&{q)bZy7o2*q^Pbgi8d)I>FSE-k?gVhSZ>#T zGFNCiu?hqNP45NwyZR}wMv3ViQo#yQ+E197vW)R9T^cEsN92)A zNVlu|NWSm7^e2vKk#HtO_K49Ybpp##y?1Jy$+BT~wRdG2&WkBz0esbJ)essPPmQ`F z^Q(5ev!>W5OQuwZZqzhlK9sH+q&mEDEjNDv+fWVRo2+@jWgu7KQIo@XHlaWuQcJb^ zDxAJc=)OSFuHyq1^d5hv9u~obpJ|B<v`>_heO^|#U*zg*h*zqp!oZc{x z$QH8Pk-WYuRWgQ&hq0v$4jYvSrN^ScCZdviG5z5(1CnIcTuK`h|NfxS-NX8)1NjUq zlo8nMYP}-UI7+fI(2{YL(QpsbX;!-sy^2)&b}=9j#`Gn#f*$ltI$L z6wQxAmEOiN0j)!jBBKO~Br3ssk`l940roKwpe_LPiMW~-?$S}N8$sS15AIp z4gEmsni?YW;u?ZkNF%r%d5eq^@#_fGkH&eo8#8I|9@C2i?5RH!ij*|Ey&uLA+_K!I zJ6kZ7J--!zK)f)glxvlmU68p0>J%Dl(VW{q*~2cgR@jQQQ+p=gN(H`3J-CBWsdF?v6=xOJ~kcC zRm|SznCw8YdTVhZBHQ4^{D}5Wt+2_;h^|3u0fm#ZqS~A(LxX%OA zZqHD{Ds~>!S)fTSLN3JpuYS73>RyYEDV>$(w9Trej`qq=0VK;?Y1=i8>* zbdYXdJikJoMBwaQ_Srt&QUx;4w@+62idM<4U=Uwm=%PSHn(cjhtZpe%;Ur?ug*)D8>jmVsg zN>1!F!nD8o6H_;OY&lzJ>s!dBRh4GwQAMLI(>sSu4L(dpp2>__ zOw|D+I{K9nxvh5N6BUVJAKM?4+AqRxT8&YzxkTHl?1M;b z;NA@qM{xl~Ns8Mb^xDVF-Jji5rP9YUhkD`MZv;(B zS;bO;l#ea>{gYP(kj44@D8>p1 zCtU2+c!mT_e)_$r#vXGcd|^w&9%Ci+F_eG)F~g(Cv!4SORjQ$0EiFuAN_CjoK-SQ5 zH!($2LUe(e{s*us>d!(jsR2keFdspQk`h^P>=7+kBj1w>-EyVfYZ;zsMS z)E}yo75`?6$JQzenkE%t&v-!>G%!0rEPJJ*fbOgQ{;RJ5yb0Qd7{bRKbjUZlJ&|leCXzfygbrNV8guDkp!JbBn+Zhg5jh$1=?oK}?g=JEj12B>TZFCKuIv zNm749@*U!VyzF?5mu+&u6mY&^EHU%bWW=D&2F$XsaC-o55ZP6$XR19|Q&TRs^G0uq z)XRoHO0EC}c4A8sGNZT_d_<7IxG&={`e~&*z%vk5hBH$(M*@RXdI(@ZnP`;SHXg(7 zYI46x4aCf^U~G7mLSJ0X@GqBTRcrXfDhB&) z!b(IiB1>B<^GOhF?*r&NYYfHiSOl$?S}annRTs?~%GZ5j6jn(}*t7rsU9s=|9N`Cj zEk`X+pB^!$kOS~lbLjkHe)DAhU2$rc*1qG#!Zz>7G>V5X`T;MnGctjpav%&ROWV(ZOV*H12MwI+P~Ie;;GkSRhHBjtNt7V^yk}1?&n*74m}MLVd*OkZE4DtV9WR!swTEzUPEOfe$&igXe5DmrRx&A9rA_e5(&N zcSpu{YB^EC3V~NZX36+!k*1cD8mlxWe33lbq z-{d=z>&C!G!<-j&`LlhhBP>W}(R3MF#F-=zIf8wJWbW<-edhJw{vYUcc%G3Q7+N?$|uZO2CcqtZ)4vm zUe9X*DB@Bcv-|Qh4%qEo293fb+YPotwU7o+eIWPZAIRYRegj6qRFvfD0#WHmVsqa5 z@3YRhs__~msg3IOc8myvBv)o`WG4lKQ4%kp^GMmuDHLNPZmPEiN>@j3jtmo-$B8Tk-z;%LCx z=&sljS$6Vtz%E(eFPkK{2)B2PkV0H3?^J~OyhJv0zZ~q62Hyv;V|85art#4eWM(*;UbY`dL(szjj zjTZSO1&JA|4=kUG$mjbGB$Mme)AysM0ckf6LHsqgY4)frINny1*#`q`Ahr!S&-q!` z-a-q_!949~e&l*p$ooM3X_ixIB(Dh=<3e*{0wardoQAu+MkPi*I1dZb>VvKcb5>kv7%<%EQ|r--da=YKtEPG_e@=yL)blnf-in z2v2wm2XqoNP{Tf!P>-%42eu6Og{6PYYADOHJIrB``&a4XBm`QNO96)R{nm$;0?gvA z-mNL5J&d?nX@nG%@TbSYD*pDMWBgs0^yAVutl(KF(6nzIhuN0 z@=$)CkM{PnnrL9X&qLKVRb{xi%v7s(tEJ6KL*S|5S5@z5x_Lc@-d#KNA3edr#2FS47~wdit2HkHYDQF5$sDK%b#^o392SZ4J=NuE0PGGQe~4D73?q+3 z+0P#ospbKNTZ6pXh__R1vD@>}J%}2c&mBtN)~jTdPqS$R3cyQ_APNafx@0Tf=0 zpWL(xbYM;J&2k*y3r@o0*&sNC5(ORV2csgo!W~BeQb2LUT;1z-l4A3Y==DYtMD+;i zGP3#lpmhqb`x-g5Yl~iGO<4inRAGhX4=tu@W`Uu84-0f?D)%-+=4p4z^KwRIflD;6;7Ip!)Q9wEG=yF_AwvEC07DQ2`F zTzTf0{cfD3^o?Ke=+`W4`i@&q{@i$Gg+n30e+}E>U{d!NN|1ly53u)}3{!jX*3GDm`SDrNt*yc~w zXqR7RlE}8I$(BExW|?`tDx#~)l@WLsZbZS4>meMg4~}h4wZKl3zYY?`Uy3c?^{2XA zYWzt2fC3a_7yhRo$%{O-YeNw_6~s7WN$5G5r&M&s!W6WeL2m9aWC@BJ3z3$vdzi8X zdjh5da^zJD#o_hcti8Q)8bev;2+oK&#TH0t{`p*}gCkJc%ziON1a?xn)bm4>#T}Na=CU&7>{BiNSTu}vCkz-TY6!0L{vCN7VlNPXdYc$vC+`cq6l;ECS@GEj_qFK z!IJJi%O8v%4eQ2k9Env5G(WS;^y{&qN>raCoLm4NlJ03u_KE?jHjUl;7_Cv9;p?O} zi2hANd-cL5u)`RXVVdF0KyiM;A^_>guo5RFDWAF%m1^k$C7qQhWrU?|GB8hmSXV-r zggMM<;{Gimu|}i_oljW?ChFZdaC-U-2DFiUS`eqoirncGr#Yk|aNl4fKcr660ep+Y z{6&;+z*M^6j-R{cF>}&FH90jttCT$O1MU=uW9IM27@QGeDqF9%x?$#NA*j`n^@yp9 zMB+-LwbeZzw*TN*>EKb2T+u~(!bUoo*>c-iU zDWwi^)b-p9$c|1V4VPn8^h!R^2bRDGYO`;dR*WC;XzBn5Ey^t@bIcwz5ftS9f&P0p zWOLpOov)L(>kaS%Iw|;GD0v}&EcyKvaV2=Mbh!cx+stvc_pIv9C_a9Jxe{>dcwriU z(CZm>f?1%g{+j$)bya%yBQ|U9vx*Z4I*xgO;fBS^Eet z9D7P<2}%%!kz`Nwq-5bQgQxovjQ7*?Q4XFumkgaxG;*KvH)8eFo}%oX9!;4b{P$}c zHL8Q3Se70tBVO+d(#)Fo6#U*xaWrMIfWq(k;x8-mzI@fmk^7c2%$xJqwC;DSb^ly0 zsmA4(ehETeybS>6_YH9yw`7IWvR8PHM3(y|q zq#|7v?g{s2xA^gE~=SeCLp zdBqEtJ6R5W2m*3Q#1-#q@P=!^J||GkZ^ELBu8l&PB0JQN~S?V>q8#TJ6~cXOTSi+(5~FZ0ab1-4k(=o=nlF zBi}rkxpixxxE6}FSb##Y;x56x6fZ6XifeIqFHUhMKyfHgyhxDZ5-1KOIKka5H~Tx^ zKKG0}?w2oU`;5}Eh7w}h}Jw)%r;w7071%hfm(7{1YUq;nj z`E+L87^tJ14%mOMl5V7Ew%8i$L;S}^fTJjLK`%K90wYj(Ju+Zjj_!wPuLKgNcQE>} zaGQ!b5vG(Rj1p$?{>)4I#{l^O357$;RWGd~fhtRp^GEWqX?#VYgVdOdYg?f*3Jk2s2H3g2{)7n=6o$M0UOe5GEEA6O|C*uXh@z5NTB_zR_rwqZ24APTT# zcbbH9s~H1Pgc*7LVR5%PpRBaJ!WvRgI<(`n{2}AD_{B&}Bg$~LhD^vC|B7MRnJ0ih zA$)7C-1@bu&FhU0x7QSUh6dWP8fT>vaB=vVAp9$S`s#jiv{l9nJ|MSnX+yIWDC4HFInWv zx=1n}N1Ydg#C|=oBFMI4zb?0TC)0}i?b)+CK1}U?it&Y*8CgJP{A#39zOWlSj!wNd z2KLyy%mwi$_`p7c?O%He(VI5_sb7uQq_XtZ$y3K^pG%VPykeD6Unhwe|53kC8Qsr# zqnGNV@VQAGF!~hst?1&p7dbDBvAPtB%d7G?92@H3$T5Y6)_`7%wSH7;S z7g(;p@<}LGvukjSJ?+ZsNHT^kXNkj$R!YLpL|0O5n^&Jbf>_1v|34`ofI?M9uPd-9 z5SGmN_p^f;)fnR}^2LHIl=&&g=%XjwMZsXmix6^#{yuC0juIR}1XcA7e@Z9ePPz0r z2!}h2ZYWL+GIC>?;!KqS@n7(r2&-AnNwU$~zh`vFgCQyjv6O5o;xP@fkA`XFhXA%W zZq1=a=6DfNc&XxZ{>zS0lIL^vk;JRbdMLUdThTbyJr9j=U|i$?84G8ubg6N#+Mi*) z^Z2fLFK|MIq4eY#V@eqBLI8=@MQ%hrfG~$PhbDpQ=eZ=Cniu&(@>6XHpr=FAYfU7D zq?&g047}lKA^~F^Bk8|Xno}P3YHx43zu^t{-F9d+0}hjh%m-z~dB1kYL$SV;T8zz4 z)n5(DnkwulsVktg6_CKscED#6%~<;j_siWJ?|T{WzDd3w`Q7R6@FuZQfH^y$g$xC# zBkGyL10_25#(lquCmGe@M$hf=SEUEQXkgVp@Qp7uI{xiDN(E2k!@wZ7_x_3(wC0d<`AEiMuS_!hCADN4aK8!fb%8p(@qD^&8nhg^<@qnxy8 z!j{_(@Ke3m;H!Zp#(rAtqyw029DfmEAK|PQBVPvKYhzQ0Wu$SWI9Giq+p=tDG?iYY zYZz%P$f$eXtRIVf!*l7AQEaH2pbExu{}@Mp62D6e+Wd)3oc+OQTF1<&of`GBqm=9^ zo9J?yhjHA_-F`@kk!D==@M%Kd=Gr)N0JLorXMQqn2{{rJm=P(hzhT=l z76H8Z#wTp!Vid!8Ma0K~XZO)cE#!x1nP^`!o6bD`4V}ApwRD*-;V=If{r35dpC;tL z6uYWv{O5}`bt44|JZ!FvV;Lbte66)ooey?=-qljYUfBBqN-nf@B-S<$uB+03YlDQ9 zFZv4`nK5{kXsN8`8l`c)Ksoxkkv@&mm~O@lAqO|5ZVm|g!g>P|W#^{)4spC0oO$a$ z!oM(h;<7}THzYiZ@e3MeDV*jeW6>y;J7pZhzoWXdcBH^~HLC-q6tnWFF+gP56WbV9 z8lL5Qq?}00vtkcRLCITev}MeRb+ulG^DZ)x+jBk`7YqtzE9F$M&(KVVtTEkrPA^{< z@t{NU)b5WYj-2|9vj3-7X8Uii3}@Ft^aV^-mzjBpJI8@lntjnCi*e*)aVrlrDk^Xm zlrpNSpboT(oLNgsC1N8T4gNE*IP5kt!?yl5|r^nJ}zLsFFbDu`{;xjF@ewH#K`&Xdp?9- zGS~W4{=8n)u;z%jjU0p@B{*%-XNgQ%BZV@A(9E*`GRen$F>HY*iZa9f4H>FOE;W8Z z_to6@Q5hrH+9J!i2!^%oG&LRs(-NI1mWITez^ zNaTS@DxqP%`?hlu3eaUrWj3nU-ycSOOY;-Ahftp+p^C`)4=p;=?6456NwDU*MXqj1 z@qh~<#{%y=UX9|RZaFzd3hmg*a^pCRQr~15fqkls!YN_W@d+OrHx9{+$c>5AQ!3D} zPf9L}C1{-_TbX&&AHS>Cer!A#$(-9vR%7rL6EIV6Kra5Voq4(t>_W42@6XO*uiF6A zaRa&aH+@ZOBKq{h$Hv1TRDLj`e4b6Z#_RQdUq&%|G078yc5Cwu+ZXCunbjZW<(z-N z@(xD`y-tk}TXF|@D)-xZ06FTKXNGxBQ^35xr}Xb4U#nCgS01c=(rV7G$k z>QW-*=lg9uOkzB50FCYJGF2Bud?H-m=968yDPF}+edm#;VloJogNm{)c1Ha5t5_)} zpfawS+Wr*B@#)>Pfzh9u&Gs;l2gh!PRU9bI_*TWHMx5{5aqJhla!ZKGsZqp5puO{4 z5T5D-LM1SO7T<w6Jnrl9*j z#8T4-r?wB*ayP1ig>W<{tPkifUrr-3{fp`73np}6!S{SO?PG@rxMjfA&w7EJ|H+c( z4Ys2WVN~FW7C-&0-jk`SbcgZFBZ*#xFrLf+{cAu+r@h-m%)@eSFxg#17Wu{(-dx~G-IyaWV!a#?bRp!_dqvWOE z%l^5uhR`rD9stEbe}v>s$dU<4S^?Sz6KoQo;ZUa|?M1S(4>Z$va}3SVYNUY{F$K}< zlQ&1V*TrSLfLRoO_E84xx01g}sF_3CN&0KMnA)E^9O>C&mK_S*LXc>NEk36*%qvSO z0Gl31cKRh1ocic{1iLQqo}=dG!B-v&clF|C0gk~y0St8Bh$ZLpw{OddZ7tPPUu|(K z*E@9d8*tTg57Nhfj$y1nBkd>Y8IZg6zZMn2w;BvlMz#X%yuaM(U?*W)iVX0pn0PVq zJcos?MLRxEKAH>AsC4ev5mD1x+^<_@B*0`?7h+2sAhZ-s7$SE5%|ShQMC2R^N&upg z9`XuLt`me;NVO5*RkF=gz1}P$+~pHumkCqi$Tm8k-1!*HF)wXYYWeX?f9v;mQZ4q} zzWPfC0}1+pQG*nXQ$O_XU5&0+zKWm3lTGTF4%GnOLfNhi6P13MHMZAUSXOU@e0ylB zTDV}H+SEaC4@M_9TCuJY_R6QN){0C7_KPp3lJ#R)``fvipM)^7fJ&Yl(mNCY+|dE4 z6L-Me_w`0i#>xtn7%jBN24T1k_3GU_dnGy!U~;m$eZkj@bMM^xSh*%TY>xzT8@lq% z^mv_^hRw_fE59%-XMSeA0_KG_-*-#78O541)If9_OFI|KE7wtlDo=DxT7wnc!tp9H zDq{x!svBx}{4VywSNu=pQNn1h96tq8_Vsc&y{mimPo#6FYI2haCH_FwhuYK5h z@aJDRxTy9p>YU&_cxwR%%&V-BJ$*~f$`o)a{r}WUaN%k{@0DMwN=ArNQ}(|0XF$}X zDijg7q_sFmBBYjBrlHSHPnWlV0@BGsuj!^NzJTFbYdrU%@>Mjamj)Ab%B3n{+c-}m zIi5jNArlVwaJg&5Ui^P6*3k^?-Hv0#=5wrlpj0K^SbaM7GAd}AYJcx$DFMHOtREf4 z$Hc_wLLcS~ouq1XHo?ya;5y6E^m$)3V`FM*X=(9v&Pz%~n~ceV>4*8ol>+O6Aj0v+ zRpU89&I8?biXLGvFE5AHt|!)2r+-r{(e7`1(2IuPfL3;`!Z~#eeV1K2OJXY#8Udf{ zYzV^@0;eQMdu4V0`48AO94HZ%3QB-eCSi6U%YkTb>yt}9do%c+$*>NW(%|@<@l>mk zoa6zDxgY6uW>@vD0@gfXX|Ym(L$bmIBu|Gjzx`G)U{bFw2b^9lHdcTtLZUl3ux$2$ z69bs8$py2N989>{qZ}zvMVA)v%5y^dXS3>2lKdXQ`E0iNfntE9r_1NN)K43wAv3mo zUA~8W4SF}vmr8x(!efQ42ypy|52II)<9PYPB&b8ne~^BN>UCw1=jyFUKWe?da_Rku zsgOFtzrb?V&B01@Sbx?RsECC>M3-6QEJ+a`=E*I@65sdEhi;-mQ=?`=vWX|`9}kKO zT?>j}g!_))d8&RSogc{G@9$O3+K4Aayxr1XBb~$4 zzSDr8;eIf+sT~ps!6Um``TA{5rIqL>waT-c%_)myh63&V-&n3)jc{bd9oG6}Z))x33VYt6;w4nS zJj~J}x6#rx;X=5AyYd-C&hDp%;m?aU@;0f133gpA|FBuxA}i^FBAUv^8!}PzMgtLe z4sdcG`}w4;vxykG`+k#LxeMoS@*9*~Pskv4=_a+0&`wrtU;e1j%;HfOfryc2ee|qf zgA$RaPpNrrAZ=yGpSo$*SAPDaW{GfVhuJdI6mjw#nU7!|$-$X$q&m)fiE1~E0c9mw zW3S=avb?VlMuGzvwtIN=FLj9?Lj-Yy;c_`Pls;%Nc)|$1H&6V3`$dk;j#-Xk#-zI) zZVm??OXEou41? zVCTBE#$vNh^w!qa%BreGKYu0{u%>+whekX*+Sy6l+p~fpmuUxb8(#pVNvo&-Y%-d<&Bu>>4bJS}&)Y+`hDbleJyo$T%o zCGO>j2R@Q9spbZ&mh~+)*@I`Eu37%Ym}E#Y>7X*?a4knIN>iDkYJ>Pmp3{>K;@jzb zvdHDyKXwlDqk9e+D!_TeZe6Pd-;^=v2VQtrT2%Zgu)s(w5KirStzPH4E$$$FGR}BS zg0_&S@^@v-vn70h1>n?qQDy;%Q6QJOM}{L`j04yn@EzL-!Lm zUE>pu1(?8R#D{b8pg!m;OWSb4*N=Kusq4VeSW_HxoX_T5neQe6A5r4F(j!6R#*wB| zXnhX)H1G9AsKjarwrV6}n2@QMQb+g}95zGp(v24!iwBJr-&~LO)~iwU$eF^*5e`RM zXzm}?Yd**{@lf%fyQ5BivsOmVlOHUx@tly0ZANmWW}Vur$I1AMy;WzPk!DktSHLH? z`<+3L-ZOBxDVS5yZuZBPdhvJzTHbNV?o~y%_kw^j{h_SWpVxf-KjdUiSsHz7O}E*t zA+SP-qwqan+wLrz`8JzW3TjnG0MCSmx;0`>cBB7wKM63yNK$AyjN$(Ji;R*KdL`+P z?z7!~p{<;lz9kEQmr-y^B^n@2ZW99Eg0BNPUJm+ryr`UYsa7`dO$!CiJ-eNwXLi&;RC#6|t!q2swXQ zBN|J#X75BVe30@MRq0I1oJ>e&e46tWdM~Cocd$-~&dUZZ?|4x1+H!xZ(bzXo85Y2V z?!OBxH+Pg%PeV*#%bnF@r08ZKP3%*z0_uL+NeSkC5?>!&bYa= zNjg%9n85Gn>+R=%WXx66)ZlGzZ{O|~C!Wgjq43T;@5u*Tdj;KiL9QsHmm1t)s*l43 zkJ!Dvz4`5)r)yGO-|ZHET0Z9H!>?Pw#5~KcSJ) z*_JBrOHI0c4)$9Z8rmFyS=U|MzoS1^{vz@Do|`_Krf=>ls?PIHygC<*$(nJ}V{j1= z_IIH^eR$Ka?(C7nK@2R&5G|s#^6p7|`X%kuPglJxf$W0rrL^IQ;k&^)&qvy7Kp+HaXj zZv&TE06t;~BuH49RZOdy9*iw*Jo2V@AydKx^`SY30ZzStp7Hd!vP3$N8%X!98GWC# z+ltTh9}0SvpESpGpThSBF)9=#ev2kQC33Ak4<2R})LCcdhF>ahZJONx;amMh2b@!) zWi%Tqr9SfGUe8l*JkwllPgpyLhS~N(D7e>-is{r65os_;Yqg@WQ|7KpnCR+l=JS#D z>N@;0`~rN-t7oTgf@lV&-H7Vlci1K!y%4n zqf2mdc7#m_DLED{N?-fI{65!4Q2Vhxw&EM0Z-#$Dn|NQW;Yb>bo9sQa#0Z)I5?;+I z+Wb_Nk9DLlC?U7ev?%=4NkXM6yz6S5@TE-jQiww#F@S@k%5BOL49H8kYduU#3@nvO zpRY2C`La#qF8qi0ZudJ?AwU;2@5nz8#_A#x@bb$x)$iMwfL$dfNSc3R1&_1hw*=Oa z7nkpNxIhM90|(_=EeawTg{yKty|CMMDR(mprf|fVIQXefTn`w>jh$+9r82nCEoSr} zSH&nr0IsHAg|rU;o%=6al8eGH>bn0TozWKI>_Q2j*eK&S3R8fB$VM`7t=lhj|w zm);q>{cZz+XhFzcQO8$1Q8;c+jop_m3Sf^XquYG@4pPZZ!1rMUYU?8$fI{&H5h^?# z1;AW=un;N8P&1qrafrHbO0}d%mwci>qG+_&DIBgxy4v3^*W3n0UY+UB66Kmb1$<~C zD+7>jhF=f?JdDHpII@Jc(xacU`3|S(H-i;067~@oaSVi~GF$8*y+y`lr29l~kWai#s(>7$3N_)5_8qHP9WqZ?iP0RiO4W?ofO6I3-3TnZS_y*fE1eWa^RP=44gWN~ySw|l zDfd-D+BvivdDwmVeqcb}VY%6HpTegT%QRe+9qT>T{CnxukB`|C6ROAhG6C@sgE)4B^IBdu~vbwYs1AY+n#A#t+ar*e}8=*1W zDexi((Y=MvRzYq^LqZ#@A?GDJ?wsU4Vd`Ry2JCkB_9jcst{Ek+Q1Q9B zImn8FrLd6D>E^+F?WV-@riAlacSuHhr|b5I$7zWt;#!D%@eN@v$-SwKjZNh-Y$C6Z zGw4p~n0*EcO%U-qK0T2f&Db?0c7E%3zJ-0_Rv4Ef=%gASM1dKqOB_Phlk>G}FN@b& zXoilNm)M9lkwQ%kLcZMiWd-vfjb)c zD}^;8QnUvwQXvJOZs9+us_WFwFDxa7dX%LM5HmeAyU#SBkWMh}OyGq2126h7QOzXY z!>}yr(&+P0v^K7K9+Z{V8D!;W`MWmh?E{>M33MDMMm6i9mH0p6DP!@`B_F+#aV_%Q z!5AMnbRrWm?5O;rpl|p|SywYUry*3=T?nleBNoOIC@M~Jt;kkGQt!MuM!mf+`xcO$ zbyVvMn+a;x#4DZ;SzFcAIGT6$q8y&J;A>)~fsv%2;;DD`rS#TMtnYj74GAr@>L^ob z4LG#RMP>@AjjlgWZwnWH@0z$>GI>UaqaKvGDlJ6$*2BaK@vQ?WK9f)?*fBmZUn{>* zGS{aV{UhWRw$Ws??=4uo-~!OBmb&I<uRW-0HZc?HC~{BjKt3_ z9qzU|r?uL7+F^wMvN7$D7hVs=pnA32*WbQ_WYu0VeZCoJsqOSU426H#UoDIB)KBx` zYE#G7F9%>>+cngywUZzuKGu^AITBi7>*X*Uzy-%|?f}AsyB|F+V6)sy_JMcFfq1IC zd8h23?@EM@3}Y^oXYb8&uQ+;b3$zcr_=WcVaUil^46t`$F{PRqM3CeDgzXx5VdUjZ z6bH`I=EiUi60V{EE({Vh=@X4|&qn(6S6>|lAS7WsUp(lG-S~0z1g`KLUO@Ve*H8`< z^y5)u=hkm4@RRpkxR43 zuy=Zm?_;s~74i{qJ#2NNA1VV){V7^1lfNj`eZK<|5%ILXY31Amejo24)EP84z7slb z2yJqFbr3e&5u|#0%~Ri;k8hONK$|8s?#^O^s#_LY7OtqqS#P;Y*d?X0p|v!i|Dx55)1o%gQ$R#ePA{F%EZOg(Y&@XZz7?PuV+ zz*S@>!l|T#PPvoDI34~I_%SGZZaZZ_BlCH%E9-~V2!{u#n6)A+fIKIP9p zdAh?dn>FBSH%mTwPVisgR|QR-90)OO@lcIwvQPr>-MG`OFuUTnW@z{a29SJ-l zo$wpNzD0cuRPeaP1ej26sjufQ*Q%@#2QipyMJZ))xM0by(ev@8a;g;t-rfYkz3}JC zsYN^w*Nzy2E$^SOdPRaFOCD-~=gGQ-2e2q&wdq4$|NITt5v zyLn#F_4)FGVe^=L!A{lF@tN}4-o8HTLsAOA3m61GCOY;!`Cs58Omklb-~C>rwd}R9 zq1s!ghj*pZoO1%2c|0TZPWw>J+R4kG`L=g%K+DOw44eI~X`1Ov9+Ri8+SX>Uo=@#N zrIJXv%M}EE)tC6m&$dm(s&Kx1Ft*E2d^*O_x-Pl#>IF{QgxPEyFiLxQqHsvd5It|u zPHI_M`{_ds_kIb)0UW%M$ItwuQf~MdnEwN+@$}d(etmoanNKU=b+j(B_WIPl&rzt!6fZ&)wH)fUN6R(89kBGv|J&%( z_a}H|{k2bG4a5u(klZ}B14V?Q^m3OCSkUcr13D0m@A=9Ep4NvS%1(dIkvzJsNex7k z@%8g-8@h-!jOg!{_sAtRNwwJ=aP zRBHR%4IXklq7nZx|c|u*##=^xxw-RX1SV_-Mt8lR!EjrG(zu*h? z=C_F4YVHpcSzQm1eNwcXc71maCA=@#m{-rGiwTicj{^~g2!{H*$0zJjVoNeHFj&fi zQqt2S!S_|*jZM`g0-3K!3kC4If{S07#$_jn4ImLE8f?Ww;m3zB2YUPAKMZ({lP>;* zhZ}h=0pYJ__Qjd4;uCz=IPs7|apPn9y@9g%-^$sAVkv^+AwM9X3~^o=sscag!tsH5 z!N<+oLRdkbH(s8ooBw_yEAUybpsV_?eZvgy;0i9(@(+ag&^y=m@Sa)TiHz_3W4!4t zI>iRXbL)?sUAg&%v$fd#b;REtz^@_0$S;x?&L*1*Gr(@XV*2@So)5K46+h@h`A2BD zhrENVgGk|?CJ#&V&X(0)k=KDlo!^6$m+n8*TSr+ZD^e;f+znk>XOF-rvKafC;Hrku zK*F(0_+gMf!#|n`XMvi>;3rp*j8q`}oD-g`){E_sWOJ?zmFrD@b>8?U5r=5y1`NM} z@0bR6@C+@>a-k4!eUdVkNagg-#bW&S{?;N#R1}R_mRpTEKf#owJkwP1(hD8bamARm$FlW+6gK8mE-apDC1Q>yvDf z(h%{!qWV`+_i*tyYAm7hBxKoLwCHTFn;px59}9^8@?MP;bqVm}X@k53w_t)CgKu%O3TAqy&0)vh4H%8by6;o3dPDGuk zuJthyM{1>(>)Jf$NUR6x_4lL2KAkblCI;Sqdd7nkEIq9jb#Bmq`j4FGsC}=~?aClA zXJ?`(1|64VPY5GrdiBAQ*1WXogON34(zhNmb#rCOAib^ouLY6+$EjTan3D7Mpv3bTuGime>|FxW+X2C@o=v3A5i1m6BVQZ{J%o+r z2J(CeQUCan$0N^lNm(*#NpW;I-1D36SWDLxd)HsJp?3c}9w#QBErLeE^Wo*lP+$s- zs441RpX=PNNK}(k6glScejc1Za&dYpX=X+j#oj0z-%aL2G38f&f_;w2K_M*r7oMO=1t(hZ*Cub~VZ&9c;{z0xLFl!X#G&`{D1Zf3qQko1lMJt&V_$$7mBL59Gmp6C} zioK5cuQcm_o+UzX{^HNWP>z-Fq;by>YFNjo%Brfe^P#XvPk*}1GksJloLrFr>vt%E zXtK&GNWexw+#1F#WTu=AMRx}OT$LLgNW%HGBgWW*-t@})RrHl zz&d*OU%g1;BV5OZCp@M#NvY^EPFvdITW-F3CLtN6&+i+nBatwD&fb^&ftlqH5WGnw zMC{i*sk(s~=4L$PH@-|EH0O+k!y@eSgmI$p%f-=5Y_MNRA;*}=(4ERCg(-LH4>9Av zkRnFGz6AILPc}&B1q1{L@6t+2TY7nTsE8>kg<)~2XIY}N zAL>YtT;-0w3upvk2S|3uj+8CPHdc}PoMFjtPd_LxtFC@cZzrTD-k0P?Sms8@ZNMjg za))|_euLq&uM(q3KHT1(-U{|!XuVugi60=CU2a@`&xf(sJ|)NqDbFBB=8jq6UBS|u z(%Ip&D!ZB2?f*Z|nB^UJGF<8^jK*L0Fp;xusQts&Vi}O?e+90J0yG?(!RsV(=^H;M z(Vpbwxz(^FvA9i`$#_(jY=zUgdYFobfl{bT?<%XSy;sFioihn@_X;@p87uS><4dFvbRN?3ThJRx6US4m!R zd2NI%_6KaKO7!JUKfxQbqEG#$l*sfknr}tb*5X9H%7gYOvp7iK639SxN=5R%5dyet zQ2WJ+;`ZMM*zWJib{NGAQOV|s(sZKR{JCxf9FM$xH-IuE$ZXv>6@|gFk!f9 z1`m>_<5E~{INNYR7%Tjv!xMcS(S(>o5No~RBw3Q$lan|6F#Sb=KKpW7ctuUh!?rEO zbgN0)QX?x>BEXst2uJh^5gu6tTT)UL6=gWv8h6r<#4KtH712mx1P%Q&%z8X&Z)YMV zY%5aLt&zjkv$U?2^C^3uN~yE#6wk}0$LKj zksVs$uC|JQm2aj4q)+$vtnNj71kNppMg-#HWuADa$w00u4^xewdcAleK1#!Jw$(+3 z4HdofM~WWy0!r^fcLNK-#xso5fn}K=rUwz_6-tuHzxVC8A7)_m3Yh3{^AEMtfkiOv zF@j0j_ZPktq=ggK^t1`8fl#{t^F(S#oP>OKC$C}jOAN8iq6No_=RRaU9R$p8INwfn zdCUJ}kii_8ShsahW%u7%sBH8-fd023?aRDxJ#+KEI>ACMKW;Y6j%*K?+OTs3ewefL zS^Z(uOmmxRax@fN+d6wX3^>x{djI&^jg_{WzX$lgUoY46&)4_w(399^k2igwhQ5_JRE5;v+IAHeWYrpqldm{OU1)Ka|{ z#M5ErC%TB|v9$Iq^v3Q}l$a5Kkhw!sBwOmSa0#`HL+oJpYmWu8+|Y|!fUT!YD;XG}_n zL~a%aKcd z)(q(8k1J(%xF*+M$WQ7-nuPVRviUags^$*(7DWMIqV#0d>X)BA7P0v!GAg^CA$49g ziTX$r6Z6`_xzZHPAg+KT`=Er>EoLLccsTK$)94OA8KtdH#X#BKz%2gEETF$sC9S-+ zc5tQrM(8&o2oJsWZTDNWieiZ$ijCUL(Vi8cPk`nxi*ZkWE#`G#^1iSdvVA8)eg)TQ zq0^I`to+loFJ(gHnUuvr1*DwDxmV%&$0dOU2hkVS+Q&3MYmLi{>_pO@qHKsebDEW( zc@~v7w_`;k%T=etW&;TapfrDeuR0@SjP3s8`FoLu1l;PE8vQ7ai{x^nBSHO_%6I+a zt59~e)wcUAsdOeMwGFCtXvbVw)J<8Y`~4UaRyBU}SVOC1~>>n9=`) zL|Z-L-VVVcHs(WqYE0Qd=wwJ(m;@L+&>`iG=LiPvyNcu0d4GD~LCzx$Se@T%fY=>A z(W*S+k*YM-mi|X)%LE%?tCMozb}T1jOpm5vqfj)0CwDu}c>=+DgQex4PR$N}xRPmX z$&KhVh>Yb|I6E-;yU8Vc`kj{CbdDLqlvwmKAL^}&;!L-8(UW2g5et(t?|9)W@K%g^ z7`N#5>PCMV8g%?@uL+78DG}!};_Zk!F0prCy|mx@EE|y7z=uam>udh(as29%8GPgx65BzinSSF7RV#;QYFy zq{3|Comc=xed>%a|67+m_>H?$z8z`SSST(#`vME^OwP{r#TTQ_$NFtuv~;L1R}5m@ zR#aY2L@6-Su$d?sq|472T;}0{F*_HUhH2D_q@{}rgHXC(vpMg)aK7hr-Y0QB|1QO( ziZqyrI+%d0kciUAjl6gId2Nz*ZB6PP?AqNGfN`{fd$@>t2*uOVCU3MSt#f0lGsmn8 z5UF#_kuq#SQB;JPV7a5cOT$GV3W%!>F{?k}rlup}LDHpOs!BJkiSm#dR5zK#VIV64 ztR6U87WC=JCG7#6Bi``a?%d&FMUG$1@!GB;+Io$U-_Lsm&(T4vP$;z4fwF(N+jZF_Wc{+KpG};%K2Xk*YwIZ&(SIYko=k7kDQk^sV9Q0sy-K@Z6 zm9@D1Hd=01YN?$Gq@ZuMxX&+MesQUNjUs_&5jc8&w%pPhcy-aPna@R!Lea~=_6`$Y z;#o{#*E>$V;J$ zm_x^)hgA=c75-{rSgzXyvfFFoa^|l%MD(mhKZ23dK%v;gEObP&JanMUA(!A`;i!o= zYiKQWT5~+F)UOm1Ba{4~`_AL0v*kdibtT{+>n8UeLJj|RuAxag8JSe_By&@=B69;e z>TKC;dlswn9RGNEbn)W(4)V$QM66{aB(c7Cc%F5*KV@3SO12}fob^k8A#EcFY0u*z4A@Q#e3*P7PK^lczmb;e{XyUg>-tYj^ zvCOZD)Od|faQ!gJsIEb3%)(FYPW!<*^Tx5aRkbKGQ7AHzNMV=?9VTEC^xdr;D}@mJ z&#IyznIvLd_trcvn7Kgrf@eMARz0-9gY047lnx}n-At6QASye6sAqT+tE)ce`|iIJ z-iaVJ?%toR+DsojV&iOn!4W@lRIl{?V|35aFVUyKn#naEk0+r;*u}z=?;nSnx62v@ zBj$do4`KIznyxiuOp7WWMt-q-juFk~EVruNpe}b`Frone4m9s=lKYzDO)sVkoEcaw zMh~!N9n==Os5Dc>i#5}N`kM6*Xij+3$E>G-U4W{Z5UzSjrbY2s-9+!F>@gvJ*vVPotMc%gTCv%5$yMggdIQP$RAj9)-f@58*M;+byT5=tQ=r6#~)yvRsW|#Hp+4J z3LiH{IzfAe^k-qx=~91M5U7zEeN}}lHc{e%3{M`bejx2@py2Mo9q629>58za}VyP`>265C(1c|2$dmq*jD z5=C9XNK`0gxEw;5iH%OUES5+)Y|#OKT?S2mFNdA=c0-%?vp;MH5=_pZDMN3tYb5CTS8Un{5AcH6Y_tOiZ zoy=mcASivV&s@c=@88U&Z?3Wl*cl&=bCfuRX;#|BG}<8yu$OnZ=#BLSWy<$}mQ~NN zV8-UrN{1Mvye2Z?4Lk%+n6s#h_BU-uJxZ>(9VH5Y_4hx&#Zdmw0>E>rMjFI%!E%QB zy{t?i41!Uu{b-k`M|YnPy+D2e(Ca|&o+5yy>E3R?=y-Jf?RPUL$)u#y@ZtN!6aqdr zrl_Pu4D)1hANZ*;&>S0Zt&g@NcG`_v(;UxExa)jg!c^`*flX&JT|=xR<}#BKAkLWW z?G`#{u3tLqJ`ulgR8K2VPi%fb-y(k6dvEim5Yj&%U0pHSL_K)3Z+-{-#_wUG-*VPD zJd?A0c{X>Ji0RHZGdUmIWb~=b(NR;>e(Y*~vXyZ;VSw6jRZp)LZ)LFFQT4ikOr*=f zu&C?31tPAp#A9z(2$!J)ahh(=_)bHdzjoWU0Lqe8>kNz=ZnLL6jf1bFk5z{Wza-lEqF}w^Roc~)c>}}P-wsWZJqzHs1K() z?VT&)Mb0qG{#tu%m^xT2V{m#YMV=zXixxu=$wJYbmITX?lUNHUPUsH~T(Ri?ZW5H0 zFw6S-4S+dWyPBhG*XVEQz0*piTrxarv*(wlM!#!CvKjLt_aGo-cr_q0Tiuolq)9Ic z^N91c=C&G-kp%QovUW$8_0s;|MSI;Qn79h@S-ms>1wbWGB2)IIb-e^5O_&Ne29=H| zMox$n+JDC8?816M@jJ&6q+5$MiI}IPQclWp4OWiP4z1%cV@`PTG#vQa zBkOEU^XD81t?t=UJOAbk0NjUd1=ST44Cfc~yC(6LS#@k#Nsbi9q;glk3=lCqlF2MS z;5Y3?y7ljJWJ#QixzSs9_RbkO^X*({v?WFfk&NxMdfwl;d9ZxZa+SRVwYm*K2C`G{ zavAOZRN|Cvk2>xzOd8YRCmK4|T*L3Pkx#-w|QuvU?o=tjHJ6^pt2 z1NkI)&=VDSw6wyC6tzwC<}6qDlSc&-)iJEuU3+y}RfPPc^8y1(b;WYMuqh#QU;g$x z!oxd&Ufdtf9v(^^_hb_uT*(kL_U(pFi$yZZV_q@}ROMC6F?r`kW+o52D9iWP>aG0{ z^HFQ{k+#qVle!h0>JtZqs0bRxb{wW9`+fav_;A=Dm>|aZGqF$~7pC@#nV~JJatUxTHvfb7h1-NM z6_+zeWi4Ji#5_WfV(kS0OB62Z29sRLUQb?gcz!O||854I$xc#6gQ;M19Am8GJD>L{=LZ^#xd#QT*!B+|A_r&*EtcjW-T?uxAsbCz z_5&3Rfl+1Oznda_C0tirJ(Tb91pmG{m50UJ+cl|ik%bR#N~x%*6feIrEK5-ZzB|6s z{Pc+(h7}=wm99XrSgJyaz;g7nhXqF_UXeq%rB=TG1XNZw5fZf-{Qypw@A)5lwxd&@ zeyjE2xQ_Oq%zLurr=C}D&u*_*TU51Q)hncU2-#FnmrsmfJ48M3TQp%yc_LaixzFAd zKgg_8&JTn5;6ovwf}XDIsCnA-Z)*ROU~xb)uf`k1yfrt_`;y8j3jdUDn!luF4QOLl z#v=AU+@zxJeU)JnZeQCeZQ2*j1c)jiRqeAa%coz9Ec}2XsvgpDs4aAp%j>*F7**(2 zc3tEASwjQU;Z4Mll62Xf&EfK zv>m@YT6@hV*gQh$>4Db^f3k&hvW7Bbg3H3Pq`0+J$TqXVWmDb-)!j30#Rrzhv-1LM z7eDtg1V0VAqYbtt8|Cy{_1azamDt@E=HV)FV>OD~@-&vYpG_z|!1Waa5CS-}rDvMCKIhd!=9oz_BH!P4u zr?-$!E@r#fMX#=pW^j^Xx%Hrvu60~Y5C`Q5O1$3uts6$Zlkm2hwsHNTIws3vR=h0F zlLB984aoyCtvj-D!aS;qamc`uaaAw<7Am;n1`*2~{2h0-P*vL%W1cAX`qisfhKHNh z_k~f^z4uoK2ke_-9x}szp)^5{8b~3{(fg4)Hx-`7_6R6ZI_&U*^+&7peNwH2x?oku zG1g4=<{8ilXdf?GWZ3d$-`G<*_7}Bz{HE*OcE;x81thWA4d8TaKfdn#e$~Wt(X#dO zkJ4;_D;#)2BkJv(7ub2fUseCP55ptzIWo?+y0iSt?^O-K2L$Xg?cCcqAD*nl@$E+9 zZYu>PVh2)?D018?GfpM$&>Ud>&na7jvda~vGG9hRsxG856<}FW8JPQ8_x+055#Dg*9RcthmZv%!>b2Bb%x@ z*i0VF*uLl($J>28Vc>tj+^eq@_#P9a@BBV=Jwr=QZf z;sKc=QR_OA^FIhdDOp*JO6g3vZnrY>FmXm%0ZHoz3MacO6$|^ubS(GF@a!P{#Bo9* zk;P35P1wmIN0DPL8snDbhmkVd`J?zpEOzvQ+ghWBN$x>Qd1Re znLXWvwnAaow+oJ|%4K(yX`Uc;bG(vsWW9Wf zit29A&!US)fd(W5ttWQ~X%)u-#OZ&UX?qBFQNanHPvFmyC16N&I)r`%mg@lw%obEM z9XzN#XRJ1m4#i^4EZA|!w)UmE*ij`#y37Vf;!yRHc1Z!U>kHa_ph(AVw4$yO9!;1zpzk@mjI} zhpo4cin0&8MkSPxM!Ez9WN47?mImn-hLVP%8ziKqn<1oz?vPMwBqRg|q`SMDbNjsS zch)9X8=N-J)h5`+0qbn@%M)u}x6)~i3<9e5H@2j0hr(rVRWQer#3`{8}5pJ%NW zZh&|58i zqU7|)X)4|0JYCK?xttC#O@ErkbDx0RpTOmVN78ot_czi^iJzhZKb1F<@mQ7KmGBqd zmF|zPCOCBiLqc#L*suwK7Nu{_l@6)ZjTEV_IS7S)c^4NqhNck zyRWw@IXuqY`mmqZ4)O8+`h?pglv%Yzb1=I%8@=(es%-#a$*NZ)(R3nU!qHArRH;`h zRmDZ6+6Qr&vvDsB7!ll>EF+=)4K)6G)^nB3i?G9Z-(Qeo+C1(^e_#iESFghrTl0L# zNRF^mZH_GsGF7=o8CY9<9R2roha}OYGJEqJ*6;tm^mk)sCX~p@)@^PwCGa`3!Ed8) zbcarh#8g_@Ti5=5Vf-V8rdtfqylk%yhL7H$ur@?9Sp9 zqbezjneJ6{hx8BPvlk2baTHvBHSM0T-OnY^-5@6De%@@I!7HA9C|6-bFo@>zC;Rt% z=~NYH@!;cXy=Px*_tb4;*Ye?aN6BhyXktLN&<&3U|AOZc74mR;M8rT@iQiR5s8Ou< z5%z$FOpu&c&lG&oe~Z`s^Yn}8fLoJTwH0Cs>)zw(li9tlC^~E3Fm?Rp-k15So~_!! znoA%p1Rf|PTZx@4=<&h-B3!)>Fni!0;Io8Fd*XY z^Px}tnnjj+aG=B=K!oEUM1nztuO%=>6L4+Ds$VA~We&t!q5b+%F@jF1uG2vlhT$(P zZrs_s(5HKAH=3NapLb*?ETIBef%#G)V=^?-VSN?)^{CY9ygxA>Xd@`;#)`Niv#(~r zxZb!(&yTWZ82xd=XVg=A)ys~$o~XYcbqbG&-R*A&bW<&=;frv-i}?{f2ks)V(Za{S zwkfZuc=bAIxDgJ)%jU9<=7W8`4%l;-yBKhRQ<12&WMhr#H`!;j%l9ysb2WT{(TEo3 z2)QS&k$K2n;HF52I*h_7bS{z1D5O)-6<^>`zFiv%_F`-7tFV_z#j$FyL9Q&;B+c@=<=^!5>r1e zYTzVqyJ$Vbr`EV38uiNI0rt^k{x5=6IK`?wFKqLXLjiUEa&eBq-goB_vNPxusY*|`)VY-3>-oK zZRDpIeS5)aghG70@THCRCjJNNd|cfwIyc*=v5xV&Qj@{=#>h|>5_UsklYlZOH<~0m zj$7u$R~dqF=w5p4du#DK9N2D)zE=+Im$Pcu`}LUz#Q&$XDd8$t|3su3Pu-^wrrxKy zg12n*Wunmzb-i>+?U;Wrk_k8jqW($uVRGdV@({t8lVS)>Fph2;cawi5@7BMAAYU!g zJNnEiT(C9HxGpnEmm2Ob5?%%IefQ2~(w~4rr*IU%x{E;NRi(S7@p)@A(e^vpRv$xq z@tuu43dn=KohfheqEGkllgaW&hQWn`rP14MzTG_r4Z8WtPns1D2N!8JMidi3k^umx z?R&*G_O^#wj4+B@Rs?_NyPWdUd^`4WYkCc6U;T`a{m_*R;2X)KG zJ-^H4jLM7ND#3hRAWK!0PS>?q{z1Mb=yIC>PuFy&FSZb5W<(CHS_R3_GEnra(e#(P z*#dHB;)n8J9BtE3X#-~2XMI<7ag^ezPcz_njA8oWI-#EOwqvXBi1fWL)6|mMB5T)# zjC}Gu_dlNH5aYVh4fsMB(y-DdOlr^NUu{$;)v$z+hZAb_^>8wSd~{fIIN;-D!}|5M z3A0@oCc4yo6?fWAJS8}0C`0**Ogs+Ez)q)vuPcJB@gPF#QSEwknU;6_@mnq`NDw{i z?s$BsF1jGAjXJ1IW6!);#?DZI!*boSNGe{~$LJN6=)hcR2l;>z5QfS`xgXn&zv_91 z(Li*o2kE0s3Vu(Wmugc!r&H|PoPaw^xdzsqG={Tp0TpOOifycn%A0~SqoJz%^)^)6 z;%A}&M}M1?P=IjTS({r5WS35U1`xo{5BQo>PecC-Q(na0 z&sTt9t=+{>X2H3ssi{#WuaLd_) z4fZmpKjd~Q+U(7ScOR~->u6uTkEoNq4V1H@atkth$;|-Y<@Wn z!wVk76Qadlc_!_Qjz8leMJdEI8A0t+8oE9oaCd+l*r3t+bAU%%NXvEJ@9ekxh^(H( zSPvdGh_Q4#kM8pj%n+XAPAg-EL#|rU$i<}Wj~4;chv}0t_SVvIew@LQl-ys>b_Zg$ z-m4TkghfB95MY(T5%6%Ko9#NtoG2iafZx!IoHL;&?hkyB)qMb~cj?b4<;!k9WNc6= zI;7M_0o83rRWv+;%7YYWNl7RJu2;q#u;~Ak+i;;O#52Q_@Z?aaKoDSVUZe~w)k6!{ zb>V$W9*Bk>?d1fERfx*?kskELmMP?2$Xl3?muL;tD_(I-E|14y_T4~!Pv~StmJU*1 zfGRi`C*H8ZCZXMm;8SOs|1XakKUk5M@vg7=L1?6oUNY7gEvkLo|A7l_t|ikY^(40Q zlh7eyjMy))-(U9}h^PviLWHjfvGkkkDN}*vl>-4nNcdOyM%$2G)IO0;X4h?dopKAs zM{-c;Y(pz1fFBo+7~?&scVqlyC6HQ0vuEi5Jwy@OgZu3IqjH#CJpKcOKjR2VoE~w? zuzgT%OLkyWy6wxMIZ%_z@p^c>hOa4)h{mJ~PgwAqa8DOqqZkP6ZJQpT(IQ4Nx6^qD z(I}KFrP+(;yzOv{A=A`ETkh3ddB^v^7)#d>ST~=pJ(5IB){BtCFY1_)&rh+30^7Ob zSZ;yk%Ncc$;sTr+CEf69CE}(?!fTqvnvu7~Y7Z$V#pUDrzjWUC}sO^6=UiEq>i>uL*A& z$u*jk(yuEPIe6i!uM4NhvIR6B3SzHVOLBc+Zw0(?2`K8i@z_-JyaC@zvc9bE27rRR ztkk@;d$|Aw5r&5DwaOsH7)1NEW>b2lBN4EAo{G(McOCI#*NQ#%0@-7{t|&LsAd^{^ z%fyj`KHh+2F*>+bkD0sywbfIce^In2P$Fk`<6H!WjbF7}6|$gzMS=BGT54CgF&S>3%G&E?sC+D`I9(CLar9N`$PKwMG zvW1GWW+{Bdh$|hgMQ)w}xB8!OOq`s^gE{SI^x8SMDcmPGHT;4uk?@a}#8)30t^gU> zc_;qSgmwMZA=Qb=xe0z?>Z5(H@8$fy=(Z?hfpEv2)e(Yib#x3G>80y4{l#;q?k}`h z9B6FEp|ksHVq_;HIrNXAmrRTWgdLi_G=bS-1RUiw%YY{3%Va9IHVi_rF+9#05#KJj zj7u$DB^T@WQj;;ZXOh{p49*ej#PoF4<(ZZ>s0QzxhRseT2FG!M`(qxaDr*%I%BmuH z7Y*+pjsi)D;`vl>GpxgGBM-3MN)yf42^~V2+KjXF2<65}PkZp#rLY{xw>fEWk+6yA zbm;x^KD+@I24{YDe=SkU!B4#B^gF-j>l;RYM!Z#;>D_uS3HhzDalzP9IoiCMrr0g} zw=SZ4!>$71I`ru)g9eC$P+%oGDm$u>mf)u~Qv5|uRAq{uR`ib*v_@KMcxwdc`zjk$lh`0 zI0A3X%$SsWhVs82514~(R%!E_1ty5_6(PS*Q%h0Sn-tN1%d*&FJSU~CHfE@P*Y=pw z2^##6P<{jf1u0mn?JTj!r&PWe!@2n z%}oheLl|q~_Sy%4cSJhyDh#R^?x;ov1R>vSwBx2o+j_r(V3O$K+ge8IH$N2wdmt6w z3fE|FVM+q|)-yQyu~X>Az$p~OFw}d2^i^BGM_jR1EcAUSo0j!91oEeI+QfGNQqJ}2 z%g4}Xk`!}2J_LH>WVeMww0<8+@ssFy>?1}iC88bP_^pZ(C!s(-IdpQEaGP|$WyH7o zg5Q(Ta6%oYNb0Y8fOyjv3cfpNhCX}k5NcejR74oXX-y+NfzDexwt}hAri_q`c(1?I zV}s8QR|Q8F>i{|>`aN4+$Zo8 zcd{}EuBtY6&(Dg7k-ZSxH`LPa3xDEECYVG<_q#O3F;(Ml{-O<9Q`Ct}WwUNcL$vjwTnww}HPWN(2N+iAEw4@KMyc}M_^_ouykPY)arYp&cKl?<4E zUZlJf3b=lxNPbl$bGLMTc?L|@>wsG zs!;wgfblT}ex%#4QS~9ql#|7NBJG=(?;y=`Sm=b12t+)KH4u8fmSVjx1Jez9p(;8+moaBXJ9< zVFP-~Z*_9z9q51cB4)<)s&e}{g)gzC|Dr$7sQHVzXA`P=J8vWyZOi%SqKWcduh4wB zt$?VSOe)`trJI1#z)TDB-x!)p0`66hrmww$UvsAGj{Fu>f~a}~C=HY)jz)`G;_A}7 z7x~g?qJnab4YRd-{r|j0*EZ~}dAELdrq1_FR^>wVa zLN_H3!jFG|e5qt8KQny5i>!0LPp#PEv+1w7optC1K zzzgu9SjBo?05i9Xxp8(AJTEqBjaQFYk+8oDC;raAh#HW857#tJ_{3@2ewz*$K$ch^v5OIOoriVRS zxWJVY|L^z|L;?z;P0erZ`>HaVNrguYgpXOy!4%I z>o4_2!?yrO$1SHa@UbqL9XRXvGphgJ%RZ?jA*pf)-tI6d7?j0U|Lv^I2;$r9m~+iN z&`{O9FjXq`EI4y=@J)0WYC6|dYNFyr1Wr9VRFLI?hxPXU@B3~3yeA^0wF{IM?fY3y zoe53O1f{>9sNim8vEPyIA?OPS?knsp_4Qvx_Hyv zBs$P!X?R=CpjW^(t1)e3ceGSY$@DLF+4=uhe!tkZFG@?Z4_!*ag$k?XW+}9~tQj8N z2(oAxWMh`Fb!j(7mm8hD$h4(Gam#Eb%bO6n^Ok>>(=|)_uJOP=56pVw@-KnaBCP+n zeu|q*pm&xPrhWOe+SMVUWT_8J?lRwrAKWTeu-W9xNjd_)vF^RWl)9|CMb@EDLm}`C zimPlyK)v?2ArB$w-9pyY$&AHb-<7ou#Z@oI=+v_QYN=Q#rL;A4#~;SQq6K9XGW9Mak3Yq_c7Ppd zH&*2e5As-=wyzzCbY2RGoi>W4#-|jO9qVi|vKLw;?SexFu-&ugS~yOwKWNk|7*|tF zraJ(?xi@nC&OT(hMCy5Gwe;4qQlE?Fx%VgZi2HH7BHm|Io1-h(@6L8e^9Yw7uh(!h zuy#+yZ?_AD2qjc8Tg5fr%kRt7<)7M=>sF_N69@8>l)VvGr`JG@t!UD9-2L)`n!-*T zz`1g+5G6wIFSFYoPj1zYqOIHF-8w3gF1;S)l~hz>FNyYgwq`GC5k6^1Lq1c}Pk<#0uVpP(YM)qnwV&M+Vj4GgXAaozUX8I3Z?CrBI5yMv zMp$kj?gA0;qNypc@?v`KFNfjTLj&(xJ+Fg3CXa;mTm=kGHCI39`6o&>2a6P484W8 zKcvAR#qV>PUf^-P`FyY}<6$@WejW9#?9JZS-*w<75|WDO%fI37T?naMtWPvdD-?() z@&(i6E}b9hbz2s`bv(Mg_M?dh2$w$(181p3P7;G{zt?_oS?JHr0!0S@Y z91xCq_93B(%lN`KeD~}N35hy$Js0h8t+tGaFujT~Nm+t=*@q5)@VEBaI@h{C1?o)h zJ(~yTv3nB<8L7d43RLu(cjec&ikpS8Ix|wS*@!bL5)TOxE-8we#BfTr7dQ&NTRT`)eIeygAQ->?Fe9G8;8V zfOSc=A3|CU;aw%;Ft#;5CN2G1)NJa3sCu!j(y#KjP=X`Y*!WuEokkkI?_+p>fZd?^ z!nrRw`Ps~)%H+SVL~r7?ylEHWbZv?wqfM_epG(oBqWO|%Z06DO=@Vy$jW4(hN-ivB zIM-iXW6{+ko&U8hzD)hbGi``(xO)irgbPhePJVBCnow=bp4L!XS68R{bn4~6%ggI5KzZ!b!A8zq^JtGY z2j;!ZnAk}USPlp<-46KJWdlscsemax6P&z!>0c%&kwu}BA~N(Q&)uG(X3Fsr0XQeC zB*tFssrOuHl1`FZDutrCf8@UBp6?zc%u|;c+B2o+g?#&cp}U%ocG#b-zqGoURn>FK zaJHU};7$^>{$(19yA=4+bI~O!hyO5Ghnui$!szENWHLWI#jX7=I52b*|28e-4czca#OuHL8F2=?ky%jq%_$+ z{)JMPGZq^^6>J_u&LxxLnVsxCB51wb+{dFq#flH*Iw=1|iiq3LHH~@EZ8`U%Wzu)( zzRx*;>jmvpe+`J=&%D=|-c+_#$SJH*G&BfthCi%j_2X(r`uO~aT4VN@REoozy}ct> z$C8SP+6KZ4(oD-UYV0z)D1;0fjzhxK#K|scO7fI1R)}xFgMZZ5SbuH>wnrz0mp8?0 zi7DR9!Pj!2rn0|GO5+qNQ9Nw3i_%;6!P)OtueW`RE3TEBAYCQgB>Fc)&Tw7+)iu*4 z9m`j6BmOMBQ->ehp3ze?ciMq0;#{k1VjSuZxgm-}wFtYI!AxEj9+!z&cIE7^)m2N_ zb)tDq*58WP!uhIf^gDdDpG`3%2RgR@BoZAR*gculyl+`I=SaQJ4a<)4{xw=81)qim zsannc(MgiG_I;M)ML6#DEQ0VgHlaC_2H^C|#_?CdA3Ox6sys5&KhZ)OKz=Uzx13|e zo_j0ixoPArhsjNC(v!@^hK0Z-rH^?QdO+XY$YY}cSgOh`uus#1x9N$(ka&&&ck`Xw zh{Y}K-_BUik(raqqfBKFW%J7XujLkl3z?%5bq{vD*m(pF&ACi}M+3pt55TlmQx7Qp z?dJeq_-BA>hW!sRxgN`xZnj(KygL-0cb_&!cF!#A0ES2{50`Vb=6#r`pMP#&0=~B5 zv+}cnHyb3%xgz?x^|+%#d#u?3w>zgk`!ltAjkZK1!bj~w55o2{H8vTj)VSjJoPfpO zXRE&?1G5n{0bl+hiZ~So{+EBPw`XeU>+0(*yACOCKjVtMm56EbI4}?ak`Kny_DB2r ze+7|hG^&u}oE&c?>#MMVLfoZzCa4!GO^i2T4={JU&qw`)EelAWIM6NaHe@5D}gE!Wj`RAiGQ8>-SDZVJdz@{uM7pvpPQ4{!Z+) zNiWjfQAGWS2sVQ(Gl5*6P&@CwWrLF^hg>Xal&5@0)O2`f5J0+n2{538GbR9f*@fRW zFnx`ig+G2H*qO>lVTg%xXt<;w?Rhj`m_d-3ZpQ+1#Fx580kxAodxJ@9XaMtBNW@iq z(RYiN*%KhUPNrQgASZU-n`1eCFTyqnym($V`lT7I5a8f{{04&teUECW1Qsf{i*Q`Z z{tkSsq`v!6H0T-YgB_qvGRiV4`-(SZ2mkAjyFH_ARn zUjz$Rr3KBY9K57|4O+b4VGt2mar8T%n?r8_)$-ZlSKX|;-gj+1LX)v|Z-^z(@?VKe z6aoB83Y`ZNSbr-ieK<*ZKy&#cht5N%Mt5~c=WjDTzsEU_zXC@_9A2i^eI?J4?a{ph z9vEKYHrIofAsb#t3v@AL#-Sz93aKSAqW4S5aU5bS>d;XFca_xTr1+O7%F~L>;Mqx$ zSDPb}CXTk{C_SgLYV2pMVO;nbM)1tPzI4niB!< zRpqSQisH|A92RUYej-2$mT~yPUp77V)Iq38}wiY_+wC-*hkY{-f{ z*YMv`E~ZI5n47VCt?|(4YHbI9g8;Po1Igccp~00qOW{pUzqiEyo&el^zAyk?5p!9U z*>9S2Bo%PZEB&y&@ZA%BHY(0hW9F+TC-=f?B)fHCa7l;WM&RlGY|q~Jq>toz`?lDh zk(2ovv(F+&Q{^O&C-H%KkgbtZpN+wkKV5)LUKgj$Sl+g8oBJMd2Vdz|p`C9@V_kty zK6^5py)FZTgSM&u{kH(0?8NY`y@}5bLpE?~|B%3`JhL->Meq*L4t;NTN)j?MnBh%M zOVnGrzK-?wrV#G`h}#JgOxr_0Z+XR)OfW;jiH0`I3q=by^9Th5Ks=L8nD@sIY1`*s z!fv}WIHGNyawa1njVQdq3WM5bYHmJy2X-7FC_~q%#?guSxZ2W7w~y)LSx)Vt3QKV* zr(`%XUX%Ja6Kd{1fXNE&(OmMWaOb_>yFdJok!tX`UqL( z0;riN1C>$velq#HjxIE>&f2lV|8X&jNbdeABDx>xv@bAsswGi;BawqIymT)XBAKWo zvK-q1!;q0tX;~av0=%!T`lE$fG@YlefxN1wD~a7c5X8_ z7{#x6Cy3zvnfR7-%_A3j5w%H2H>LsiHrf6>reBh8L}dsYF~$_X2UeYrwOUWX9Oxe8 z1=g-N*WNo)ZeR_aiYyUMMNpzvlc%|A^AQQ8Pz1_ax ziHAJJWvz6bSv4-OY_TxuiJa(pL3cvyGP%o0qzeWW`Imc4mwG!)m%`NoXv)}mvdE(_ zf9NwFmJMrg)YphS$hSXEytW^H#O6H&8Qtw{2t0kRpK>>v(_gX81{^r&&uFKbJmEjbZ+Eo(h8Y?jKO0I%7%BSpb*;@dsH+4+zi9e`6?oTKn zbPl1T9g@aQ87+INOqcWZgQ4@$SWIN@h8fK{xK#5uc#3W>c=0l>DE^7`bmSw46po z*DiJ5<*8M(lRizM30$TZ9#6C@)I9{DT=wwlnpTZ?k^x*C#dhIcUO+EG$S^WFV7lC7 zIQQObs)J^QPUj zxcKItVX`Ed3?nOLTzzNd@@i$p!(qb< z8qF{5F?AFlB^9xj7d*miONqW*nrz;>ll9nJR+9Vewh=m+v|>V;1qiq(3YYwipCRrF zmtJ{+vCqs~W_D9va@|+za$XkVH*S6W&izlLQxvbypUZ>k_ToZvdw62V)r4UxxZ(WV!lkv~Z>UvKXDQTl7)z1-9!A_*3$ZZ|6KpW%>zZ_VO)iz8O1Xp45w z2;~A)Gbz8@-n65SVKj^7O&FYR+vDaH_K*nB#{E9S7jCTu0ZZW{b0nAyP3j1LI52Z~ zoEk0F-crt!jPAW`Rou*OdpiHdqw&OG7$EI0>->$WthQCs09d3r=iV~al+B|d{${Ru z;8GUyTqyPd%U{WOND5hLLO#rdXxCA>CU8@y~l=F34?AZ30G%nG5i3@aX?zU_| zTc{|3(&J|yJD3d^cFCC%-v1lvBgc?)hs6G4xI;FFBOU2$=*DU{S7`-S_#6hF<@809 zL?effy+wGj)sFbYw0RtWBx2pSe5rl+xz4x8rAJP-pn)*&AtazeYL3|eP)lYgO1PZM zy&Fv}RtRxOIxs|ki)lWS2B(B5pU>N)4ZS`$U*bh|D^|_`%%^~`2L^&8Amn-^Uyu_R z+zS@;i0R}1uc8T{D(y_)8j1BgVR#|Lkk0uieSsvdtU}EcO$Qe``G}4O2{0;PRM%?S z9xK7#BUW-G?oL8_Xp?8s^O0o$skgZwd^sxdqa{#~$}}Y|qgf~C@bNgJ45LGG7n$Ni z<3>PIB2GO3RzBH%3*(Gh%%JSH1Q2QZ0=X%}0YAvR=DjT8-YzxlXH} zNY!+Y#Y|!czNe<{Omi^Ju1E$m?Mn}&6vlbq*G7EfNJJ9S+E(Z4b1`W36Z=Qa*SN-GC0egaxY~U) z!^*)AVKAYblz*_vE)BpM>E$;KME4~k(hnF|fXutdPjAu8)g(@Ih(7baQeJtYC|Jz zzB?to*^zFu>V{anM47NiCAJW?9uWhd0(11N#!eL0Sk0($tn}i;6>)M1C)bX{s`E;{ zsO&92)$I~3`3`<(TE4j9=zT84`|}kRxn8lOt*vwS3DSTAWHk~A%e&~+P3!PMa!662 zRhbI}eCp|qY;tX~IjnyxpL*+udVCTQiy|cAB!RuRzX^E`N@SO>%H zKV%KbZ8fa%O{UCl_N(mBU4;?Go=I42?$7@~V>c1ns(Bb10)I;&e*&H!uH=b?LecH39eGwT%!UA>GU(%v zS%55-#Hf<^wQ{ezt8=8as&$h*m`sF(_C=2~J0RGSRU!h1>i8FZ zyv&t`b~hz&tzbau=4;lE=hlqT4W)KKtV?cQ=zPlD#?e_98N{L;}G%hUj zqvnca-o!>3&h_ok)fCCG2C^bLb?GyoVmtY4-w`ry{H>EvT+jJ{!cZNRY))e9To+Kl ztxH|0>+RJZ4ovI16A*=BdKF;yZ@K?ki)_RTbN_3Z7WjUV1`(OB@t2GRwVM;k<;pQ< zy_)RSOY9I(4HUFs+(yYbBqlXVNtLZuniS7- zE1pP(o(tafZ~fEXWGZFy(BO_fEu(lwE0(?v6x|$o)ag&iwxXWuWvWwNiw-CnVOI~;L0OpYs!04o7`(dmgU0oOT-?Dp5Tdd+yFB_EkJ3l8 z04mlUy~t!Dk4V@==_!(cX%GcMVeV-0!q_n75-7*E$|^Pizh$lE|;p>>|S zD7&B$dNOf4AmB3TBCs3Vyp=Xwt8baLDb@I{grF8AEhs=e+?T) zx$BFs6?0S(72#g-ER7UrFYP@CV%+(*PFeqKN!5fhMz!KXdffLT*8)fhXdqfsze(f5 zGLt-Q(#G6ka~x2G_M_wkd4A5Ww@U+E=+n6 z5~1s;`7B4~A$>neb09{+-}2LTdJL$nwuV0Azr)?ixJQv>A?6v&=4mH}VmQ$i`!{$0 zABgZtnZmu`p!l&(6I|XolKc z*`b73cqVuTc<6eugSf~@n<=f=tI-T@yZ?k;exTWwSoe=mo)S#L4cj$>)llSPuqt%X zxDYc3P=hD=y)%ua_&jZT2Mtx_+ToP!om7CzOU0QS#&aEY(2imVrlW*kSpLFK;hrcC zh$IvDV;juBfiMlYt{OQ+y$-txqQgk$@7LWfy|oL&(QU;jaPu7D+s{nM*0y(QEY9b4NJ6{q z$ZlGHvAPnqtJ0ez4h&A|DQziRLsERNKWYJ;W%g%UW263gF8zZnL8Le*@q{x%x)g0V za*ie)CRMy<-tX*2LQe0$B?6}hJ!9^>U;>{$5uvF|^NV!0n$5+N=9Q>glJb0(6ugSB zh3F)KUSial&dro0bwsqhSGY(*PQx^BBGcB8s2F8C*UjVGa{1{J<(Xt->kV~)YSLwn zA3b}8d(*Nn3wXIz%CdPpmxWRaQObEdkL7-p?iT9)jF3rEm;*0<9^{lc3!sBK_*SEk zn67I;3tvsG|N5|9o;E7$=mCTVDr$cT$8Qm(dt-nJQ!ymoIk6Wb2FF<8UF0O336n&z zsojDpD3(oa3%-1U08G<~CSWw>d+I3; z1NmSol&0!Vg{oY8!#fRWV*gGHc!1r|pA|mDg)O~JIK1yR3{&V%$|^G^y+17iRtL1*(|93pC+w^GmXkdT94 z7*o)qOE>7Dm46D0BZ}hOihdykXx~^50cq>D7|fjg`+i*uCRIoj&|%aRIcRLx1ZI?n z`w#i*hJYMU*-(XSRkcc3L2fhRKFTwj(l~-LQd#GG$VA8_A^1{cqH?HmTCY#q3PZy0 z8n|MjZW2fjzr}*pc#|&9B=R7DVKCsa0@+e$>)Xqq^<@2gQHZI8LWP_)qg{pWR@Jf^ zRVo$nOnn-PS*gc^nG^m$3Mq>Z>p@H}Gj^0Li;CwQJ7|&Jm*dz2RT|NdegKL@Rx>56 zJ~MOEaA8V7<53s&A>J{^<>!s{G_{(K5$&@AKyi)fXZDsL37b#^FUl=o)hyfPcHkH` z5U}nQ@gu_vGe<8EvWfvW56N6#@*VwMVEfnJWT5fv9x`g)J6FBD4UUshpiS!c`6hO? z2r0k)qnYHf%|P&(^s+yi6v%^qi`*4@LNvy?0a#rR+|pXCCyZtldqIy2Q>eE_Ep~)2 z2myL&^P<#Fx#o!c6izTf5(Tbyk}4ttBbMIXMZuW8W8DuUmM+`u``zUZ>~@b93m^+C zs4D+>gQt*kGno{R`L3?&+#N8?K!iu%d^2K<7L#kt$k*OKTO1Xm+Hu0${)<|JKM8ob z)OkBHwpl&C-c&U2Xbrqiqbc<{Cv54V6!syiVsqUtJt*2Ws2$Dy5@egSwegt9A+OT} zT0kFt+406rQL1JpVmQC>5^c`txl_sITTS=!jrZ zsd2G~MC^2=DZh&DC=DDI^StzO#`$WxdHFP+BkGO%Wt&CoX|$LKF0LPhr2CR?Qb18d zs{yAZUX1MMUPNoKUW$Nato58AzSNOU!di6J=twS$k6kN5v&PK0jglwOB<>k?j5zaj&&z9lz~mZb}a?b%4kxwei%URVD z&Yd$Hnpj=A_2)?KJngAJTQh6qBBAstvCO)_Ux=$Bck+z1vbZk1@*OdCjfiNZs@%fI z9JjqDM+d3>O6F+dEVYudL^}S-=Gy)>a5b|D%K&S+$x?c+uv$Bpt$pkN-SPLwsBt?? zLMOaHy$-eg>tnPMk^I5Mm=U{)`t??_%`OC^MJ0mcON$aEfV4I-X2zDp$oVHRCKXJo zw4hcBzbV4q>=zM{5bKa_D6WwiGXkBe0;nJIR<2JU5Eeg9Dmp2Jw6(QQGhY{JmZ-WX zt7tX-v)sN&{Vl?Ss)XQVAx~n^Yz1Sdt)>&KZ-3=0M~>RErozx_(D3hdW{1@^;BVvQ za<#rY!xKH}B}{ylFwuE|+fg`{lP-&aVKC2lsj(VuzFCbqT-}FQ4%U zx)JTZ!<1p+=sb`24t$qOPBaSV!Va^ZiC!(f%}ndr zM!$E(pB9aGo7YEWZCB?tQl?D?t*Mw)GGDV;x(GMB@69Sa1kJ|*=2#Kpy2yOjYs#eE zU+aJ{RyuFiZ53|!uxI*xK~Qh!YTYKlyNk+znU)rioeo0YvMJ)bzv_Xum?Lt14{4)9|Eyvo zC(NM5LqsO^YK)|4QsFZFTC@vGmm@Y$b@4)Ck6$ODyUaPSG6?+<(5f_*_)sJwMW`mW z7TOCupz1$??a}+q1>%@Yb_)A8ox53r99tTp*|I{ zy__Xnp~v~W*Rz7`=4CIK7Oq>Ju{~2#CFyj;Ua*)@!zz!nKhc@!&?!%&{`eY(U{7t+ zdNmCTZn5{yXhRsMB%Y_U7+>6X^7uUD^@A1B_8+?f^XIOpg4Ib)OCO$&ik>3K%DY~O zcqki*=_J1P%$mg*RrSX-E)k1UO_~FrMvcCaVWD@zXjAsb3Jg4Xa(?u+HoM)emciH3 zPSvsgd+KP+QhRqe1zReg6wu9+zfzn!;&WFadH=y8Tfc162>6lT@)UwUv~uC83(M{gLE zp%8l3i?O5*OL=UD>%4T+VUJfPzWgwq01Oq#nN$r4ZO4s<=q>)vo}G0V5;`Uf3%a+c zfO|a2xkZs;OKu~z8|^E3FCSFAvEN->G!)+Hm}<_=W$scM-jU6i=qz139bE6n@G;&| zsV@KMZP4=VB_|{#d?#`?%tNp!T|ypeCY_zflN`<>^{KERB41Lg5U5uf^AnBtdgZ@MLaj+ovQ!oq*VI1j@fR~0|9!ZCLQQjI>v48AdbaTnx( z=nrV#3@wO?eke!6*6mxp``e6oG!xX~=UR_iF~0~_iX*DdTIq>!!f&(uU#>ts#Hzxy z*1XjyFES_&-l;J8YIttdb4y|IRTYl=xa?MB^Ct+A4*Qy^+I?cZ+$FO$I&K_xc)xw z+FO1~K`1?+KTN*KHIoome)uq$d->3^edq1Cd2nOFn$+c86L7&%$NlQcU)(Z#mN?OJ z1Tejt-}X&c&%k`Mc~6U;ziK%iax`^wx~JSpnk$3HZS&DdpEuf;3>3vz^`tT>!uolT z&X~PtG~mfS^{sPyPlTX*sotNv=j3I#XI9H!KjU@-OuHyh#DmnuILg%$b7ZPM-wIhz z`Am}s?&9Z)n2kRqB3mV3d0F`9yXgueQhmqHVoGt2bjG3NJqUMi%uRe^j&uJIy-c3w zAzSF#gy+h^IVY%I=a=hx-Mu&4Cm*Z z+83ZP$pd=@AkEZwxMgiVT3H*Sar-vgsb^~m=rI3aVMjU3kzL@7w2ui?$!%8kCKEx| z3b?ccdE-@ zmr~=4K0#c1wshCp;;ViTf!X`#UYZ71gTyi2NE1nq?eVm+&;AQ$1+ zV$=SnKX6DF<&l>vE?vL*WD?iLC(?3gz|Y<_{8>$mJ=q_t4>YLO_uxQf8`H50!1N%+ z*G>nRx}t5mfPY+H))=Nt!`;}{=*~+h}`kxeHDk<0RbRcxdYoe5Kl3_ z@@Ne;`x9^+c#(svJ8u<7{+6iGSXfy_b;B_w0C%X5<0}HF!dl4VWXR`%PgjA46|P0G zD?)9#p(;jP(XYe2ebFO<;U6!)Qw5h9S5KaK>{1zmd)vp`$=DO554iR#(qB4NtcEI* zREf#=pwZfH=(acM{Sa-v0UUv zb{m$zqp?^se^cB^wwa1ss&%BWUu^t^9!145W8uMVOR3N%pQ@Xu2U;1qOOm~UL;%k z>8kNF)2BPZf}GOBt3KM(ovj7Pjjs>874s%H`d1s2F7|s1uX1FFR(<`N2n0Acd~BIy ztZidh5Gb6x+rRI`<53uBES_xjDlKLl&vH*CEiMlUb>F%{63-7_(#A8~} zZd|-SWi0K18vXSTxNvKTx8YgC?rOSG+GcbXEswcdsV}KW&7OyqV=lREoSj8F>8r`F78ykk zrDKktW$?_};I)7I&DL2N?`4jb&X?^L+=klF+Adt0c<)oQ0G+E>?RyHW?bNybgyWZ0 zyp(p*(yKMYiRuCDWfgOfsfMr(pM&GR>PUI#8%Iw_+%qp`y=G|s}s9ZLV z3|LB$KfSz4-pPD5c@b%#J8Hk4Aoje({Iw;6_eKrGNRbLE|6}TQ&EVH<()^&d=&C=7 zAyTq~TlPH7D#3MD(;gYp#Fo9!h?pVD)u+f ztEtAP5L?|5c|Qk8*H^v#@n5G~z!vZyAHd_=xYTnkKJx_(vQM1FHFD?3(lMkKh(hQX zr?>YTujk-;7bLvg`2Kry!4rKl{bN6Dkgu@3{*oL0K4#PEYrG?8aa*2t!#DcPG2lx0 zzZwVYJIkVsY z(S}!V#Jji*9#sBg3rBMGYE6h>cKM|i-+-DG0uu*db*QLqS?2w% zwmTzB39&XEl)CI3Fy;PHcz@FpO5Z9uWdX%@*94d-^A}?BUBaVGxC{jHuO??&A*+^O9d&Ybj3a`9Y zCc^jd=ea1`=>0P3RgyP6^~}T-QK~L=Lp3o;)Ah^20m(03Y%JyezxM;e+%#5+wWLWj z?nx`(8Ca*sIA#1^@5oBWi%(7bv*d=YVWDZJ*cn%9!R7h;FPHs&`G9Hns((|Kv%BtdUr!l(r51%k<%Zz{?y)g$~NxjAT^#e&!!1inU%kn+eLsN++22L zQ89FBYrg>{OX_FTprQ$%hjJ6M1nhWcVl$DeloN-QeOMie{p@WJfK4}bBMPKiW#3OK>CUH+hKQja@x z!8SOpncqxoU!_zeQGdCdBqSL6->vY}|3+%aJ;W%#nU)E71sGlr@kF-I{C+mDBCjOU zt1h1wjV?tM{hqK8@HyGkB)*lmwoKyW<~6qHeSrVxXFE)~RbjB%k*BN4wG^^WEciD4 zWWCqDz|>FHI?LIH%+=%W+tzo=(UBey&ZC;1_rdFR>o((RZ{iVfUr3Abj=J7e@9YcWx_}v}LYw76lN8J!VN{hceg|u3um1fqORnK|wUL5@P?psTW z`yw7q_I~Dl`#t9MP&CDD={DBt*RFDlNsgH6Mv2W*6d1`_mx~^kHN+>D#Z6O9_`JSM zr>owdzHF}ae5Y?WPhR|t< ztAnA>vB*o*-|_iEo^DuKCIu|trA2(Je055Vy=|E2>^*Paafq!be(*dMuKRT$yz`dU zrVKuW15Pl#327!RhhB}bIFGm}8M6_gY=0+kELAb@OA0D~GNhP6d znK}(}rQCYEmmT{a_V)H5hc1xpF&=$Cb#)vg4&A7yj2~Kjqdwf+KLp>G$C-cZF)^j5 zr$4zbiMdyt?gem|`Yp^MjLvL(b1n4B%;>w*Gy%)%XqvHeAG2$Xmp= zB;NtkF+J-5h+$7;t$_#c#{OqG&Pn<k91mCzyQ$s;z2lveRg3gh0{Uy-LKmuxz0aVr+&f8T+Bk zEppJ_@kWcx1~AnkO=GNH-h8!!%T8|k#_csmODwW$(8|C0rd8~c@Z1A0bi^je+~u&N zcclm11EW?C?pW~$k7J;?lk|b*NdhOz{JyY%{5tra^OZa4b#*Vuf!OA1r@ZRJz~ur! z@C5)ZJxY3d`j~yE88*=O`PAiZTW2{v)u}RxasT5fZ{k88D|#`r<)M_xk8!#&T>dRa zr7sNjqK~N^)akblnV3&w-T0jN;>W-DglLQx7F8x~1<>mKkdVyN z<~C5zYXq>4bwPXMX4gl|USU<63Fo6^$Oq_*(?q@b0sZi87I@FT!NDlXQ{Wu$b9<%M zySsg}TLlGLqUQ12{zq6DScIqOK5S;Y4sFwlRsX^peZS65 z2@_i0);c5MBN6p-?Kxw{TZ#@f(gr6^TQ5z`-SA*Z*)|56u~JOr<;&*fTHSmtWoNY0 zQ}qJM@&VQ*rzV^?&TDh+b5mN=C9B;tO5rwN`SHsk_^}@GaT6YhKg(_JP(|@CXoxQ+ zc10M-FZlK*`#nqMaZb-z^vK(6B^SNwud)9NulVi$WsrzJd zx7zDo&NDk%H@xc?nwC&Hb`ylO2)b=75%blb;6+0DZUky7nJZ;+>?JL*oXG_nAxVo> z^yNe>pB{9&XpTao#yPqb#f@Smcbt|cqK*d6c5CvtHoxA8;8xxNMOLTb`!;$B{|CVR zdSrPPpwCkFD)34t;FfY`bd{6|0#WzTu)yM8(qR*8RjWo`;3SG?j^{@DTk-LBVD(Vn zuP|&-F}d6tLwE#yJ*qA}mCsQnp}+?cr7Ct!ck@Ff8v^v6Ch^XtY(i%+X>PBxEw9}d zE*navLE5FivZC!F8)+6hXQM#O83Q;YvT^x=p&!Xt`O4xvf%zV(wHoUkq5x1&LjZL7 z%va!#MWoGG3^m_R0R8v0^AS^ekBTt#Fx1G-Zqx!h&14C^M19va| zY1Cm}5ayhN_!Zb^GR%7)wypD8XxaBZ?7TsO+`i2lrzdEWSLxDJb?f?!x~itFAL$t0 z&JH=PNm&gRcwdhB{vzY0gfd@%Ob15QeCVeFDNE}&)QqfTNS@avOsrL8UOj#6WoDM= z%)1s}Ss2Mv?k86y>-)nkGo06IuK>(%u88WI@o?N8MkYllrV5ptUyNKfn$AbxCv zcW}~vZ-X36DWd-1sYoBbSCy|qEiTx+N<6;%tXR$Qu~WyF5=hq!vq0eix2wRuFP_?s zp;k+z?){=kR-WWM5cfqh=KAn7$5l%$;^9&{o|IpXkx)t-HaXLa{k?M$Vx&f-4ib9< z5~SUB6xWQ)%?JX zQZ__8N7J}l+z7W!DdXp1adE++b<1kVA~t@tNMJf34E6EDrvexoj;i?mixhT4okNdm zF~%H^f>!x?U_5dHu&imJ1EBQjEJ`(D86|=I*$>shL_MSg99lJ77wRO^ zg*RaqDtwby$E(~93xdFBBst*R@*DI31)3@2L@)H}qD?>EYk$|A9kqSc5D~v$7$^2= z6Ww#=Ts9e(dKgHU42n&_f7I6{Pd|f3-}l*??a$S_-DLUxJl1~%#N+`uV-{o`dqXY3 zg0HO5!{K{`??|oZ{jouQ&2O;P{O}?v<|xskWcSCnp?@be%MVlf*8Pa*K%)GgNv*dX z^Z2yjJ$?+yZMgwW-njJ|om=6Ie@Qy953%A-)!NhJ;3-3S53P4waE+byl63INBH()Um))Ai)+ciFZ` zb9n>2Wbn9tz-7iPf7o)pk-6^fI#X@#HYYLpR60>Ge;NwP5cTk`8zb4QPr|S5&cwPX z%Q&Yh^l6XQfz~Vun|ux+`f2t*-=B@Eo`fle7J<3RcLpqOg;tN=HjTLR-RbGlXLy?$ zF@s{`a^c?={cg=4?yfOnktNa0GjuXx#2a{6TSkC0bt0mlCoL$Ij0*R%qNaUz+AGWZ z@_=0;(pSa}Tbnyu*q!k45RSfA1Equ)KygIz5=^Nmc55Xe?BS+cupj}F*i;vFx5D}E zW=-Rt&20drj4MW9s}*%j8EJK__n>M!jzRAA+ozpRj@nV(0ag&f8uHr>LLm8O}ech6>8oP>8Ic28syhX;rWL++t zHww%HN%Jh_OK#qDdy)BC)E}Qno*Ur{W2|{#hTJ&{vMxF6cCFTTZ@P7C#x+h`SGkeF zQ>Vf~j{Q|88iFAX^}|IMO_OOJU3@DCW_(!>&-Y9|e&xO9#-sLLI`UX9@ipm$vGG-g zSgkWLu}eFsbMu^@#OoSG^JHRh6>^*zdI$pJOW z%7-qRP{Cv0U`{q#9GLkPDKucc+OMYfc*#fRQh1PdiCTun-+ZwZZ1fs;%F1PWx@*RF z*iDcZMnr@V`N=iQBCcKnMB!^3v)``c%EIRY6aSn1E8;53~<1%lf|>D#wf1bajynny7Ce269{>sCcyU zH!f%&l~4DF8I$A{2E-bkw=o)FyyrvQY78_NOuw6<(u#xgJkW{ba9fmoxr&OoUO&7} zm?xc1Xg$RH^)U_FG&Cqpe*KOH@ph zLeSU}r?&labF*+TjB)u~;WDq9h8+w$f@fO491B$6N-(-E zi&6$WNhU*N%_1K!jn69xq2|J{dzY z#(P9kz?u|_16yiWs$H2Y+|0BTi7>qPtg!yRzHoR77T$_$&9_-=-^j}X^pFFehH`O7 zIJf)VuPp%64~~BaEFY-Y+f^R$S)BBKXh%rX!fFDMet+r45;sbs!O#c!L^I!aD_hXC zmap!1P5el4VxF;?=j@O3y>`;)Z|eDk8nwllEDuyJ^0g~{aI8OB@tJ%QOj}I0L228mZ-CIn z{UC);;1YqO5)s4lfvaN4jYx0$mHezoo1jnEBGphYIGTK8w!cDqYesfbIv#&%KI=8rX)Yil7E)v3)#&D1e@8@rq9|SHWZW}J3 z!r~&BEv!uhp9M?T5kC$jF~d`CL8i%43EK~vcaIKQ4kI%HM>Y{jw8XHt-X^2Om<8au zrzkjf7v+5ItrdJ1hXk4W+z^b2h;~PdVjfGdg)Kq{4;e~-jRY}z$czV3Sl4!X(_0O} zq|X3k4Yo{|yU!2~Sm}x$_@+f{jo{B1>?&AbGgd`6eb`g*2NL3hf{!ka%2EQ%bu|fWi`V2tWMqI zv{Vn}YSy!OO8`~96h1vW;v2NSqUgRO#_T)s+}9wmM1r(dzIfgO5GF|IHQ<9~>!~#r z{uj5#J@vVlQ%F={9V-Q_?YLy`Nn;9zXH0+NB4qd5IL|2h$ByDrZG}(j`K!2^DjUxg zW-aTaZO7ipG~^ynH2!Hc&V@1ES-j4zW%;b>mB5S8jFq1VF{TftiM)0X$ax<8r-E-~-1D1CgX>OP)!u($r^x`Fdp zs`qvLTkgGj{(hdO&@m(fg|R_|k8u-`No)EiX@1wEXAO0D>o2mqino!W>7MjalZtqp`lNVo<)5EoR(jlN~Xocj*0 z&$=d_vQnWXWz?U|)0Ej@Li=^&-=9FV4zT;UlwM_aFUO00HVCz^8U?~tzX-tRqpz>W z+2h)-Hd&8+66-q!!`(OayDpkYj|l%N7lKb9G^L$C1GVEF?eUvfR(SC}!2WZy92qpz z$}r|0>c?oe?2DC8oQRG0-HCvw?9I$!u+5%(XmC#~9)THp5KS)WI^gD*wU( z%v7&-!{2@5sA*E>mxK}V=cj!i8WbXpkhiXuP~{d_ZL;+)^%tJG#~)O=nNAqPRf&Y! zNZFK><5b=gm7#W19OX+Xrzj4vs=t)g5lel+2vc9(0>}d+`=^jOungvhbW7efIgxsO zbVWVzwNkC4XceF&Z>FNGzKOqgTwMCQQknV?k_!DDn3QEocJ8@Gmy7DHsiEYJw-;Sf+kbTbU(G@Dy)c zLslxS%aP32K??n#@K=`&I>zc+_GSK!Ug*}*Ws0Y1noG#}*sUOQahEJ3vq{}soQH?Y z_UY?xI)ca6QZbXv+pHtQWnA+oE?D}zDutw}{(<)eiMuwm9cE0amB`t?wn(%-K&-l_ zSx;*6F z>XqSb!YEKx>U}45Spiubf3Zu7W2&8iMKlWJ_l}RxqIyx7rETn{C zF8!anKB#uu-ejKc*Zt8%KXv+c=er(aa1VZ~OrsQ$6vcMMY9 zN~Lk~x<6;_jIBE7x7LyOAcfS?QMSe;0T1Oz{ylI%gqAf4+4|Lu~ek-1LQe zEWsKVPObP>k`bgc8_q3*4|W_m9U|cNyYL2v=iEi%%6vH?^oJ2Gr_UBX8>J65LNkB$ z%u~%Fj!t%jl|!;Q#l>w z+aA%ei*?_hhrZkGjovWIM&BietHQEJ#lL%CalPco1%I8-qN?`BIujPX9Jdc1UI8Syvi zh$UYjzOibVIf}ol5TdLX6&@Wgz5-d?vQT|IS8M#3-L=w+(8Vg+Vna(rl$f;HuuI9fPL>iJy{Ydh-AMjIHv2JLMv zw(y`~tN6BB`Ph2fmzu{?>$uSH`@GbX?%=v{F5 zo;!>6TlCviV#8a;gqz$l8ejC~bj;LRQghMUUk2_h9gV{V?o#4Xyj_C!!Jqc9%6Fnz zm{>a&^#2_U^BldLjw)KE5?pVF^nCs^62!w){{Hag`nchWSST=s!R$(7QphmGN4lk! zuSpTw?T|=6=u%so@Rh-4D5kq;sLke6H(j3wdNNtS6L^zc!BMhGAbf#t*eJ;K zVJhkD1ta~O95`+xHxpWxrB2qhmSNM+OdClh-P&M=G_d@pHhv|eqo5eM^G==vh$q1pY;F5eQe(_<^5U#z{cE~xm7;!sSntS0eC z`U(D#C;iXCsu7YSPi)K^t7Nu=Ra(<9;u8zh`cE=_^&{_^GiuAdt_#buDYmKAG3eoJ zrT#nxZBu$=Tdj{T*2EMK$V~49%%R*Lr`mEYvoI!mDKRLO3;{pX}bn_3D@+{n@@->XZz9k|;UbM83Qz`Gp zAU~xDCiA+Z5IDbMblAFf7lB+658a>QT_qZQX)Pi-o#WaI8CmZrovEq(JYf_AaLJs;JMh`jkzel(4zoX6RvPyb6mS;4g-2@yK8jq*ehR1N>v)#X# zEx906n_Ucf5kUIkDde^3(N0~E*06Wh)-4NLD-cZ@5GM1@UU>3!m!a6xsKgguXonRD zd3xBn>9M-f9ECoImJKAp%JUQf zaO&J}&i}QYH2JjzrZ7AtWnw==kSc&x8YPF2on1dL`5m6Z;GH(*pSv6Gg#`-%quJ}f z%K=1~-9NA2cW#&3)nBHdBUw-qLAtFBaLLVAEJF!MLR1F%;bkiC2*|p=|F231zHMYs zN*2{mrH5#s3-BMgXaG@WrwG-KBT9&OnW;Zwh#Uxvn-|br)hI%Qh6-1!weuUFV_i4t z_YL<;nEPRtvAhC32O8K@(yc3XinE9?_BdA-7kIchiNx?qT3ly()P!(O? z{KDWM81NJrZu~(M@AnJaAthO;(cLICpR>HOY)JIQcHnqq z*Fq{?X<#F$;F9wMY&wSYEGlH-v(+_^7W^Ns-d&)h21OeDk|_R=%(?+ZMOv=b&THf% zLh{rHDfUU5n1(`uehpslC1Q2oOSrkIwSD)Jz!#cS3N+f6XObaaiO59P&wDkqLf!Ds z_u0pZUri8!nCK5jI`$rX$RDthZ~BI7Wz#xPHlS{#9@yF?vPQTjN9A(jl8}%YG$gX# zu%(&Ys!ee!xACx?`dAIGoS@fvDh+9`)uopUj}HQc^<8od1G7ISiTFO@sJ z>V1Fr#taCQ+-FwX{PsHc!Ta^i1@XXgV_mVpa%0Ne*|Msc<8G3Voj>d!^61!q37{79 zlNIGxbOtunO&R|HP;J?#a6x)T)6RS`(Z&N8fnNi?t|WXO?H6r`8)$r^JT)t4B1ogn z$&IP~)CG|!meUe6>S`qfnH=2&$?%kj6Ha35CRCEK<%C(FK@24KRil`3(@z_US!!LI z;2vMYC+*v8=}?V#cC~jFywE_}ZAk^bXHQ5UbDy-F3T7>cJ1{TzAJ(Ujvr4vFDM}_- zp-)a`VyVLR?^a{&BKP7?t>9#rZTej~aM?kI-fyD|MjgNh7yWxYw`(yR%@MVt8OxUr zBh-HX4_$c5prQyq+wbupe)cX!yRw=dR%3v%!sN=2kbT#xw64#@(kCgak7E@33Jx+! zo$F5q3BdeTE<+thuytj0E2+HO>RRpY4;7Qa-H-6 zm+b2+_#Lfr1eA$j>=Mj!d+I3U$y-{elQ!!|drAtdRGv%ErHgVGM4z28&i*)im4*t3 zp0z&GJxe0|d^P)WN5KNrPnj?F1|C7G(fbnrTUp#$bp$lDwqe(;MQQ)uAq~Kt4jT!a z<=rt}FN>vr0=(Z(SO%jKQZqT!ic6l85m<#dwy;b(z*9((5p^N*)k`4r!L9pg>3ZY5 z86mG{qI<`C&>buFv!zxYR##Qu-H z5#Vqwgnt4%mP)!3z%JzVOw9iC{ptyAONCr>blXXuZ4Al4sHnEM-m7F2_~S9VCh2O+ z_^U|zF}#X$HmhO@9krEK=F=7u(+Vr;a_U-U3L4gdZ~02h@1`W{Nj>oDRL$U1)XIt- zKK`3RJyFgoHW^uM9J>n*L1O}V=QQGURuk?TXFX3YC9V~KSA};K>6B`SD0bDSYs%@6D}OBvn`rEES7rAIIhNT@A39}lN&*&c>Awiw58>P&F&XiU z&IgF@6>U%X{~eJ%mClpxoPHVS2=HQ|g4;!X3B+4k(|SN!QT~@&3)u&y1eIM<<<-Ee z3gZ@~dxrZ6x7`$4J~wt}XAO0=c;;Idm+|=Y^uXxoq%8}t8?W<5lbmtQ@hMtyap^p) z<+yoc=AA4v82z$tf?7rV6Z&isp$;PmTq-#pjce&SS9i?>{||AKK&#zdYUu~vO*fiN zG@}|b20F8T3#a$&R}mhKbBvT_l`X%kVo#CDKA7Ty!ly!4+fLRGY${*%%@6J!2*u5q zSz@VzaG2(?Y{rz~Nuwg75ZyRoZ2!T{)W?oZIfzle-#k|++ z4Vk_Kz6D-l>L#gGd8!h#wZ}~QH+*P+?+AO!H)yxq(mAEURZsulRZlZ^9h2qBUmDP5 z?*y%Wun^hSq`bXRZ~j~=_;^0Uin0xl(L>*(fVYaKz88SvTMq- zJXBsI);*l!U&UYM7~>|*n+@^B#c~lO*KvOloB+~G%n#0zSf@!TYKk94%a~N9Pi(vw zMQ3ae+X`-pFRa{lkH;pz?=;#z)04US-1gM(*fEAE-$r%fen;?q_4dMe@WBP{P9xHm z8k`KDdUdFf6AkMd^)ZV}FZFFlv{q&&=46n0Lm|fbwIX_it#!`y6K~6G+ zeBdWDyIapL!pnVwMe9fI(HCEPq?O4A9aJrQ!mqT}mS+*9;URBLl+^yVYI=EHE3VV# z#tTZhi1dqY68&pXb)F*HNJiEwU$zyO`ZkYG&Xl~zIBUL>l)G|^LF*77qlkd`?uc!8zyqXSM(*#nkDHRi7L$N?JEWSS+jG<>*T zLdAGnMi11M^+v}S)d@bhTm-)^(so{WTRNgRc@d>^WhQu6_jQ;o^2xVld1WLK@HTW0W+oxTut>{G!Mq&;_1 z7;5>4HTE2Tx5GbCMVz^DxhBnoye3V^-%RYIJi947?i#4NRB0)@0u%OW#O@@AKAyr2 zd46SogAV@1v=z0z%@Izg&58Y&p9da?+y1omhZYJD67InZciw;RU4c}XM6u~&xD@oz3NwC=uOH|c`KB1D^+Q1|5)qP|+{0APgdL)s z{8i>T8r)MldIvRp7B5uia^UW#%*CK=H&(`^eGc8MkHXu-{u6Ao9Q%Qiwj&J2RHr}O zy}8h90Sa!gu@NH?kVr7@(wkl^4~-phtg`f15s4%EWu?7}t=B`jsYp1%72zaJ>Bv_q z#rR1WiiZS&=wi9tTuBAIgx@fuOO2IQ_G;1+N@ZglqMo2$Ft4>_@gO&eTU)0_JW)i^ ziup13vk6znIPKf2ze?YxT<@8=p7`BUHje|E)`hRn<}lMDW2N8ZPxm!>Y_EoR?C$mu zU+=&7aJj1@h8$Smz2AdBQ@@>S=OGfkMek0suIebuPklYEE4tLTsCKyNbiC3d2-JX1 zpg9|v>#-6c2($}MyI&jR0;F8H;TgiZ|B+AuQB&z(Zw6s9AWWhJ`efe#otyj8($Yr2 zGb`LL5(n8`eZ#{&poPp{g(Z5XM(%Ued6H%05}5I)&3o{}eGZ7D!~>K>`MNj;r8Iv< zjwZzG>+AEWC1rSH!Ro4mrosdYZO~mB1~<_P?4sZ0fSoD2&}x|1WikD58f@!F}<20dN`FN0FxSHa9&6P8gf<| zRC5qh&h>SgU~9~mi_*gz;i+$8Tmo;@@p)CUUe-$2fGZZ^S9kLr9^oIl57%8hXOyOa zl~q1rs?Fa!f2DH#>>bSwr2S~zmYWqBiFS9j8kZ*Up7JqM7ywvSfCv%0diB^NW6~XY zxfcjMB8@-HBE{i`&>yx#9__iOQzsj7+lF^MRjIOV*4{l{tNGkwf01C4b1OPS* z*GDt>6bXr`;|m@Y1~WhvB13QafBa4P>p``6t}dn8-N=rtvf9^{)PraqJ3 z@NP0Tm{!}H)}M9>yI2ZpO6FW-9@{|?Wgs7BxV?J!XLuBW`xRw5%bWgRrcS`V-~i{c zh1X8DSQ1~}xNLEpwL|`_bq?Lt=!jv}=zAMA7C$$vR5_GH|-HR3F<;R_9PXITr5Hl@mMmHeeWXtCvm6RCL#8ORx!Q0?*0H)uFvXW?zF}j3b-X+;PC?Aq zf;j4<9x%c=+;OY=CwLJ#D=Mib+kDh;x@2?{lw4zCDTH6&oNbTA7f?%wqO|5c(&pV_ zi+N-Z3x9a~y()v)|0%Mj!>+L~H!9+ec@-XO%MvoQB3zUfLOnuFq7`F))0R>{aGd}6^ zM@?hv!_Dr=4FIjC;v)zN2?19#taRR?#Xf5PF}!T9;k~IfnYM(e_eIhsI`1uDm>hx3 z;w7Mz;uUxPX#VekV&8EUgxM)w6XkB$J>A+9EUcSN+dkdbW_0nb_sPSvqk}E)=!jL} zU6k=?CE*uTFj39wmlnX7*$0Val`Lh;@+wS!66CyilAxX2<+m=jo_RWe?d);?!3jQF zf;><9(#x)v+)JiS)7?~BA`Fe3K|B`OWebS;3dSU$Wpfe8Uaz}rD};P#B%tZR!k>=5 zAVEwp-m_7LKnU|zpM_2C#HLGBs#-u3w^Mp&E8o zq8K$QcV}X|noxjgSM{RO<_#7{w_Ryl{P=K6HTy83sk)r3 zYl8EQo=mlsn%@Vkx1w{Wk~9r5X7U=#8O- zHoCTaKk>ZxBkf}L17OD#=vJ9zLYeVD)xpOgL4u9;g7hqeEdoXWCnA7S)Jw)xQ@Ka2 z8nouOIRBDe>hk|@gC)S=HE-YW`{#9QlY#9MNUP^q%}P!0{<*TNV!CZdZSE-Z@%qJ= zO4{3WE3$c~>7I*&(_Rx!krX!@o2%Nk0sD7T1=5v>TU=`_3VDS&p%a#W)=OkO72qOI zYt@r7Ls}PH)i-DMt?FNqixWHaSaxWYyxdan(`0fDWJ z3}e+TmB(k>{S^nY1&?j7jg=5xwm4glj0&YIzrRefQ(v7(<$O6u>d1iP zDpK~I^uy){(ESyGK-OM;qCl2b&s#n6R9|;49C{On`tuGj0koysep zZOyB#=^s}s4b$9Kv%*&!aROXECf2Pyt2XF4Za7}5VyL1fi&Pd6s?c1otXM0MeQ7nd z^I1GoD@z2-ykpa3{C3#>5{`v2ETnNJuzR*=Tw2Z;l11qtALbrgEo|cx3(IMcmmgnOvAUh z89A}(6u?1N0}&51rlbEBdW3tfR);b**(vN}r+x**=G2`s(B`N!4Bs2cQs*3VzSSY& z8l0uX24R{vw+!i-!y7Z35tXSj_H#N%k7I&;YQ<$sh5)k61RKK+i<_FXLU9fB%Pnz1 zJN*`)njG3Xq=irLMv=!d5UtGF5@NDS)FGK#)M5*tphg?@D&$DoU$x%)G*T^Cyk5xp z1q|pmc1!W&rQOR>n?oTuld-d46XfdaF8kE3|yvVl@kwzurFSgKKd zgt_ct+og#sneNBefhO6Ep}h+nK;c@umT9i{iC~M1E&P_)K{n6jF$ncTAf>}!AY5JN z>%?3}j*GK)XfTYW;;(4ony#w<_Q z9_ISE9dcHt<=XY-rH#+fU>=-2O@a_14*4dL1{T*kFX&Db;Yc^oP$uKUn!sKM51zud zQLFVH^zGH(78)^H#cqr&N1FWUi!>P~*wWK&DzI&&m0%=S2;W1Mdk#vK&Np{EW5_Mj zv}(`|=fT=_qivSrYHX6G*_WgJQg2K!Pa;v>Sj;aQ>0P6iwOVgn;n$Wh5g|rJ_S-WL zX}3fASFNix#4oliMT8I7TyIzKU9ZnPT(9?t*X5VDN8_~o@SFWSU*ue$=!x9-k8K?- zFMFKy1aVjVrcRr>w!Awr5Kb!kT5);W2g?Uy@mIf0H_B`N6yj`=y9{yH8j}TJ!Xbf7 zTUMRCZZ5V13!2xU3@=+EA#^^WN$(TYdyD-8*dt5MEFaPU7?Azo*Ybr51ZI2Qh&_%pJqb!*5OxY-ELRt zS65BLb~F!P6p`d<{^gs|2vD(@w*;Mu!^@N>t`FX(#(BI)*AMWntq$iDIuwW#mO}h% zuY$7sp7Bv*lqj^eq4o5DsEOeu$MR2sMji|N{ZY~(F(pnmsm!T&f}O)1LC=HKF~+J<{oE?Hi6vx>)KP>Tt=<7UtfK_bd(w=!mfg~pM} zZLhlCf8C+@p2_Nctlmv#OHx}v)QNAd%Y@VCBnt+?ZT61de&yAHF6G;qL?noVsSo3V z)2*-LO>6x@SobDgNbCjE!m-Q*oPQhMjiBwg#e7CJ^diuM?J_n;N`qN}_x#2Mb1lX8aXwANk zMRY?B?39~-Gy*dXJIOf(b4_$0G6EYIZRuUsf!)4=n#~J%Ei%Us4WpR=$Aanq}%mTu*!_)GbMKPF5Gpm_-HIpFP9AWXrAJVYveqX1*WVb8%4Okttw3uCmg_v?-mzX`P7MQY7EKF(WC6+XD{r++T zRu@9|B=`MAPhQIfG<83&XNc%feyn%>+>bK-Fm#$UwU5EhOc2i(xVTPk6=B^)UFRPH z@i%;#Sy{UQNr9fZ_RsWpd&7R;?&PAh=jlza&klR?!zd#YXypfN0||b_0-e*LNni|U zrwo+o`S>pSUQYId04=5ON8^c^8|--))H%1_NEBz&qE$rlW@ctT;z>%qUo(Y{S{}8Aop;mX zoT`t5Z+m5!%BPY+m}BJV*ZaIt3nZ}!e-)lh8@pUXd&67)3$J%2$~PXiEjukKb$o73 z{TH^1-%_w#C#(w@^f+P5ru_&uCkJ)2>Ka<%tqV$Pn^yT1f>a}sJi&oV732XzUP8`+ z#FO3e3dl#Z&CrH@c-`HMI@KWb5OBEA-UiYPJ3cGvP*Vx%#6gZbc7OkF7D2k_% z!VH_B?6BVbOU0{XMz!g5LukJvTNSdl3NqR&U}sGZ;3Lzh{$PRjs}=y;P09w2U(O`+ zN!GI2RDJjChC>}Z=^HQzU_ge5r6Rb5U3Td1tNxsKr;Lu>zwER}xagul_#5T@bU(=3 zbdJd0be8H8YZeO&T~y*u?EEH&=(5K?=%P1Bbw5V3;UG-)P@FXJb}{DeTygha1b50M z-JuI@qiD=QyH`#BYXdL(fX(<9<*0+*xq90dmbQ0S$Lg|}E-OdAUQPSJ{by_fEsIEh z|E9wq&h0rys;cg3$d;|xrs%U&dTSD}H;So#3o0dF@i@N3Jb}*XRQg+C@X@aQa+~g5 zA6ZS773^6py)hTZ_1Jbs^?Dt%li?xci1Kj-?zz1d;ysAyt-_Ogvsd+RSYl1KO)K*f z#*QqJ@xOa1)doIa?^1*mHJw4ciDPKuPdO}VgKA2bMA9< zUjwyyVuhsDnh-UN_j!__W`CmzcOCy1-ld*wWIaZ+iB5@@>0iCU$$LCbr}s4U+7{j6 zuSX}-#Nw>ye>Ftx%&294YD&TNHEF0{u)M9OH?T#91Pd9xnO%1*X#EWM&9i;OD)Q!j z{AB}?%T8MTxND>vdI2hSCriCgD0YDxTteP?yOD)1H+Eiqcf_Cr55e`ZzRh$ty+~|u zn|g0sxI-$Hqkf1^w65Z$;Ls)!<{$cs3_e>gB$lr=@;Z>%M$TW;#3a0|4A(8IkiR`% zbt%q}VpnUuai>waNp$5;xBxvYzva`>jeqRmZs_>FhMT+MO!DAi5aW`r)wI}+?@B_^ zFv2I1+5eBJvy6)>>cTxK4U$qrHwq$BLzk4&-H3p64M>-SAkv)!i1g6iAuWw`*D!Q9 z+~a%i`~L2CJ`CsVb@twCJ4s-e&F(@%lt7ax&ZIQMKXcQ9Stw zKMg(|xy##&$5>4*z?YdB!B{PdLNxSU$=2Up_QmX7{cf(Ojtu`wBWvcR_`SV+juPO` ze-cl|+ROJ%=U4-b@%+47k@w$NAGLcvZLVQ^8>hBi@o z@B^KxX{554#r6(?N)(=;9!@7)wPW)>o7MH;?JviAG9ZHE74vP2gKgu&o6tW?fMUS& zvC%I@+?EosjO4B^ zrq1Ie5`9e*r16ZlFB&v(+)B;#0CDr*u~ESd2t|pC_?=)}UoX{M_Umkw$nR2NbVX#F z@`76SH;eDsq%H6Rqe2auOj69*$WIkbjy;;I4Fi;o%GDi8HXO3^27niP6wHg|hzV~H z@i~`q-TnMc`U}?P3HCR$Wh${IRKHmft^~~l`T{yyYrWLjgxIJLsk?DHVbFp_WAyX| z=79c!(QPxLdp~#K`?N9?6|2AIUw>kjdSY zdRB_u#C9&%Y{a9zH=2BTt|MBHFEd%q)~yN(lup$5Z16r4hkBLWA=D?#WALLfc(xbW-1ZHku$pJWtOTMdC&y84e z_YFdFuO%~b_amWezbU0cw!x<%R3sK6OZDv}yTnAm;BAZw;JuV7CE-mlfqTk zI?dM`@n^=5zxMTRW7y!1DQp`qU_c)I4d z4|)=Ew3Q2p6G=(g*g2$P(<&0lUUX@zVb@ngb0O8B_mu}-mnxp z&kwD-sC#M{>xAd6DVI^oae6X1d>4xV%YkgaBq*dzZGeRP1>JT}f7&TMgTpQQ+&mHs zokaj;5+zBcoiBdbDmy24$8AF5wcor<3(r0&WbctF%kLNCGXhZXfJR&AyxWkPHFqfY zrj3)rX;X=zJ=K_VF~5)x-W?z}b2vl4#|#c~^31FdE)sDm-oc%&Dyh@SZ79XmYfMFP z)h;OQOvAIS>&(7l@;2`|)pA6c6hG$DN5Lm|Hqxa?hoE>5+ zEg%ZNWP+Zzl3p6zqi_`cLca=t`K!rm%d7`NW7<3k+--93tHLv=EWp4)F!l8Oa@O# z*fuY3y^M3dy_gA6gXXo0K{rmd-$^Q?ZQChF4!kc)MG0) zH3qr8LTkm;#E`5ZF2x!+I{rAW+Hf zfM?6rV68ppm;%J1RW#L{&nd#FR;iwwzy3QcY}wcZKjC&{PStzQ+rMRxgG_`;|D6co zPx=3Rzd~V|y_fb%XyAVb)|w=07gA)f);DzU{B?RK4<`qQl(QKj$I#H)S%c~yixD9$ z{5!(a#^<;Vh*C>ZOz;|xjJ8)5>`mg!G3R+ki9R##g)Z|zWtrHG=U1G7ASk_IK?^Gk z>@b}2#UgS<{7FP@Vk~pykAxg6@Aky@BREI9$+(WK!;GAS7Bpyoh^;xRq^h5P+pETL zH&MlJx^Hy^9Oc~w4}UVATp2xv`akX+2|nz{qr-g!FGYt<1aU(0ZzjTWD5t~t0)v%- zw+UV^^{{YmFChesr^t>d(2eg%nE^HAfx zi40D!0!|^>A@>s~2_<_SMf2}sq|5LV!IV?iL{b@a_k5CS*T;Y|4bUkp=>PY|!AE6| z4_Y2}*(%vKEyIGtD~e^5_-vu7*-~b}ix$Q0k~=8@73f*)%^T9hnh%stxAr$3O2 z0RJPPZi_o+OmC1rs1{P(5)9N33B3vIqWSo2fWBuV>D3b+D#k^(g^qE+(>|#l!^6?j zHI=f^fuP7_8E>!3HT96rV-$y64JK10Ca!@M9!t6Uap^)O925fUjkx`5|7QE3$z33t<* z2Ex+Sh$d9ydQk*T@&}g_86)H55?4|IIKCX={$*G2q2}FEmikMBv-HSOSo1-|`XIHY zXN1{V(l?z(C9|`HoGIHM(X(o~Jt>jyK(vv~yTk&`MN{*SFVkCy^&henT4XCp$S+-+k7ywg0^ zyL)I8Q&Ybl%93i@H5EcsHHc;0F1GVmJYmq4qT9c)+XSH?OxU1prbG#v!^PsR`&;<1 znZ^pX_B?2LbMerb4{i+8C&m5tF^r2NOFutaBe65FtT+Q-uc@WWEZ$<6_sr!Jdg)Xt z?x&rdoWd4O?M?=})3C+ja+KP`=#IClTbr_U`$;V_%6!I}s)WOYF@(#1Qf~l|6HxrN z3IAIKiJ5MH^;|TR8mgCW{RL72_+gNlO zV*a@FwHdxN%m)P`75I&K|MQi1CW<|SL)e0KbxWOWARrJUIX(4Y;czG8!*u2MHuI_H z)ByrhCO`D<g^w>ff-oJt8!K#1#@)(>epS|Nffb`KqsThoATQO7l^W|G}mItdWpOed8l` z%fnyQ`^P>8wcB7@l&T2bAF}z~=k2&wIDoX7{NMZtzr8BdLN=4*b+lYS6j!ur0kno( z@1_x`z<2K)@T*Q;VhzZ#I#0t4i%l4gS^7z*;f7{-2yn1Y7H?|JcMgsV`D1fe5~}~G z5#IfWANkK(t2YPOg}DW4(S(H;{wLbQhIn1>N2RW)1kD^QmNw*+uvbJAyL*#n;D<`^ z2>hU0gPKT{suGixV_^_tU(2i!pEm-b7Xey18_t*&&O#h{(YKB6ZNPXrC#a7(JhBK@ zGzwA>)B-azrwXoipnmf4Gki;|?8r_HY*OEZMYf!7w0u$O`ia&J-7|*bF*1(P4CC5+ zshpHjqQ&=hcIxs<8%R>Et#w;I6N*uviP2ck(DYHey?wm7YTsCCJ_v0EX2JK_;FXn> zW`|_|^_8dF7g1seHj%|gv&bhe5%oy{`sW{K_3?@u--(aO86(Z8^st)|co zHpG+8HWb0<@~_6IS`QcX=!UA!(6TeQaB69_5Im?-mYMz z4;A(PMlBf4Ti$pVl7|iGB>G=*03Q{0UR0_H0Lv}nW`|Dg;Aa0uCOXG&y6tmAT5u6P z^mYV?ds?Gvg&V8HYE&KZ`XA#XVF&DZdac~ntH_nqfW#!lFyI~`L7Wv(E@=rMiTD#RKbq@MR~#WX z+z#3vZ&%b;`W-xLSab-s#dKv*a?$zzj@7VP@QW%^$TKj+e~g_o^aj=aLU<&9k`rxJ z#&EioP(p5TvV!-Xok9g0uIsWd6R3QEt?TDz)Hu!8vw;aQM0jo327#oq;s&udNw$@) zwG?eQ_$_}ja0;NJ|88U}d#UYKi&atd`y)#4tp9DSYFMM&Am=)e$DZOO-zq?zv^jA@ znlI1IA#LeQQKeXBoZCW9!5kvbseZxUFRN(G|99snee+wKKq!V8$KT?TKQD55%**=! zJM{fC@-Hg4vC$%KGt>J23gv5cmC(VW*#}XyzupJ8789BAHP)eI+FUe&Nn(zR3vK8r zS}I>zb2q(qpfi%9y}=4bS%YMPXdQXqk7*TcxYA!Dmz;XC3>`ZMrvtR-!& zZ$P-6WUnQB?@2nbL~woNqb4{49X@MlarzkmqGn4^(UR7wCukL$H%ufI$4l3C_a>&< zX|b`F^MSo!eVU7Z?qwUx3AkX@@ zOFJJ5y~tBaw&HQ!R&i=XdBe5;CkD}7@lJ>@$Ys-nsj~cqUspy2VgafY$Ia{0{{fw_ zy9?7Pu$lbAhSm^KG>N(P-3`bo3BgY5iOX-W*02eP}5ONJMz zOIH$t5^a+Je+Br{)~~#VQi%X6EzLH%WX~&x!j>i$lzvQaDL%;r9Uyhcp0$mHcnUk@|$;P>OLqsHsaWKEwIC(-51R%~gOSDgXeWNQaS z-z&Jj0sz!xODJN)uCO5_%j;dYqVu)4lCeffQQk9YF~VS6MKZDrDPp4twr=_2rN zcqTdhBjep0+o*CDT$Nb@#~&u51ciM8UI$;3Ul+{dsPw;5iW=h3@=M>mGF!LYzN_@+ zWFmM@j8u;aC2mG*8s&W6M?VnDxTTh}QI3x_R1NCo#Rx+#ZW2z?%-%kaD1b!s&H!I2GxH*7?8>zMe40N{XC0JcCTn1G4v zEPS;BfMtSF-7a4l)RijJ070h=kBl$$ zCbYG*n0?1)-K~cP2jfm^=R@(RVzRQhj*EflJd^^DtoES)ouBe|wJd=xyKxd>`d{Jb z6gAkW$*uF}QEy&Vt{v}KWw56G2w{~_ebnYCmfY!1urxB7v|k{&4LlIN2Q%ENNbJ_u z<4^_W+EMNg^ZC&#C~!?JvbUHJW4~QbisW?1#_`;KcG4NuutC7r7S>GE7C^-nN+rZ0 zn{Vzqt7=`%$SO|2IaAtoAM*Y6VM&q4i9e(BleEg(`jA7fGizqF@1^)NKzSp6IeYdx z!{aohVZC_4x$$&zq=mX5!yQXmC%S&=y1 zADnnGhTW0C_{pN|$=f6QX`3+S$B2jsCjg0;2PCD89|TGu z0W3U5e39dh&%$uK7i-cY&D&|VWBE!i)avaV|8d!(L{8<^R;H{pOM%bK+z)N|b2v31 zG`Co}bagMUqqt#5Qu#fUY4Rb%ktP z>mL9k@EEZ3zEH1-RTZaa9pr!4b)^jxY>#-QeC1qP=z;xzH@ferU?cT$?;a+gr(^a0 z+LD@MP>H!kvD}GSTSG%Y$gYedtkFG1C9IDa#TvSC@f@yckL+65Td9?ZH5MKMt_)z! zogbGdXfQ4>{xqvqM4jFrEx7JPk*pBk+x?4W!Cg*o>L$%tk{MsRBx86%qv%qrST5bG zG_Kug;Xs)$aHucBg7f4dfdW4Hg$>rU?Z=nXh$cttN$ItNZ{3CePLgjqm zMzB`5AiTD&bl8K%Y8={)FOGph?ZGi3(u{X|?oaHxQ!Z(&hPjONDb__QGr+^GOrI4^ z#Z48ejJAKhitA;wgeTX5oUZbrM?|aebbjiLV=EY}rGN}-{=Q~j_pEio%yF#ojn*59 zFb-B7l%1+A_aPfSBA4GH!nG1%(XkoeW%-Fulpr0A>P1GGZ?860f_U|IjD_GkL;Z<|6)y>&(5|r_kWc7eb z=EP3X-j<1n;*Yh5Bc)jK}9oEOr_-wkj?e$A7>PZ^-=;srP;b~ z#Q;UUi@1W7!7NLiO9-YEw~EK99c2I(Bg5Rt7{Lv{ren2HoF&uR*O{*-Um z!0VpTrA;k>9!71ihAyV>>E+?=DZ%Y%>4ljA?@X(f_x44gNKo;0W3P(EpY$a7F_Of9V2Z zYI9hq^HHoBw1sar{`d&y_Ev`K5yDkdrJ;hegRfP?$MimW{1n+DreL zpV7Ur*pnUgvrF1w_bc%rz~&k@#MMp!AW_5*+X`^9Jl4_qki7`6>JB1oVV?3Id}w+u z>}h(Llb3(Qt29!E(YSM6&Ta@&dmN`WoMjc9boNbFx|D(23n(8El-HX6Hj%xAQ2j88 zJ{{snz`{Mos0=l~5=Pt9^uTmskSG|`Nqr9QFV+^O0Du7-ryi?O8*$0Y=bNe8M||Ezds_79swi)0EzACIe!BC`&P8$%Fu`Gi6bazYk-r#}bFWDbSuW^_AmNlG~i*8>J``&JH z@SOr~>KtfPWk15t#J#8Icb=NI)+~Hk+K^Fe0?|U*vrQzz4JtmiERZ1lA$QQ`F;lwPDAy0pBc6i|_1aCwn8+DvJ-o1u+Y}?m6r;qiVzHAm{HeTnhDq7PIb9*{e$B zQmayHfGpPi&qm-&K(A=msAZ5-Ip8wxX@fjq_-zz@Y&~5J#*Dpncux=1LczP4P(tluP=&dX1 zFGK~C@^-OKtX5frNaKqfsL6+s6zVx*g>Qz3?$SgPBGR&DjC zXH#LtY;kAf_-{r1$?)Wo)7eG+`mn~xZv|G9P*?62Q2pXERh6G2dXz{zg`uv)VsxNU^xDXdD?5lQ$U)r)OvAb+7Fd zjy7b{i5<5K*3O;)N={X)|I;JjhsbWayc@Jt9u6a*Z42?T+?~irF=%M7sUZOjY(FFz zI21}F5-?~yBn+v}YG3~hqt^~rgJkh$b%mJ8{-eq z^Dg0G=maVi>h|g8wpB!6T5$2pcB<98K>QyFrclY>q4W>;XQTg&HOBzJ{ayV@3$O_l z2E>L&`Z|xxzL;)QVa1)Wp|HojL5$~xiKvjlkJHS)>4-3XLrj+>Ck$)=FwpAXJkC>{PW3$R8l-Y0QCp;`c&{9?Yk*q-e1rdo8cT-~5cLUIzcrUBDBo!@k1IMu^( zN*F#dtZ@ zjpJ|67t5ipBkiPC8NR4dg0~F&jiceSzR?>_9i3Ld-#N;LDUX^B&syuY)seVoYj00= zl-vqHZ!?A57K^h%#o`o}vLS#sOa&T63#%}&cP;VdN^lK#Ghxm!!^n92b{aZJS|7dI z&1`1Am1vQxz9!~iYXgmc4+Di7Vzr!jZZtguJK(g;;X+!}lC>%{^&CQN8jaL{jnb-G zTx&KP78VxEm?`kMxVTo>98kVAsHC?23zN0+dZy0*)3mpyJSIE2^0!s6L_vR2D8*iw zSx0j6`biF}>1^<2|4W0w+zzi#P5xhbNd}@fumHZvT^;=FV$Q?)G!cG0k^>h!74)fg z!W^V38WRFOma;$cejxBU21^HgurNIqkJ_KO%(#OI=P^G=39e%{hEWMRnL=DfGF}hU z=LMo_iK1Z!OH~5nsr+F8Q_f+g6^vK;u3wrjls|}yL+%hzm#d+Vd*ZH8HP1fNVh3== z3_t`3U?-a<5Kj;0`+Lt9O#838(A9kb=gPV!6_3xin9!?I%>uaZzHpMc*7Vp%Y1pj8 zLl$5ekq7M7-<(*qb8^?FyFzd(fzvwH*!Yo!F7c3s#~c9I*2RFUn#q16N(X2My$5GI zqtOnGDS2ICjV_c`00k83hp%LaXreek)%^{)nO-R}Q9hYc5x`aLrFHwR#T=oSYR<7$1nZn|J@X8Pvo-1L+{OI$AP#69&_Q9>laci9yMG? z^JD7ey>&H7*pMvRG1~Uw^dB+V@#vYnVI?}Ut5Ix@Qhvz7Rk)B3_HQTE+iD+Q?GYp-WDe1X)XCm zK7z@FMYovkRoqOeimWwH#8hy30~F~-Xim4*M~KCb7a8?VJgn}^;@3T{b}|7&H&mL2 zGkTGSYu?W*Z5R%%8(4;3H%o#io19LoomQ(RPh!~qD_hU^o9<#~U5_@Lk8`Ywe0A3Q z^SC>f?=rsmKkR(o_g~#@fKLdYypQg@{&+7^ItQKK{joVd-U#uTUX#!LbOFb{&3oMk zIxm_r-lCcH#n<#KR$VKWs6>Pj8So4mTCmk7%6}uA7UaTnv+0iGDDonLZj>4Y`SziJ zx{`v0AR>q0p+q_9(wFo)i?F4FIt(evYZL?zwbVD?UocDCT@8t|K7as!TONkr?GG zkYd5#WWPO}D!7%PA@ji%uqaIL{@*YC5gjEpC+xM`iY4xHC0JEF*%;S zr$fPxprcSr$VgxUE|tt!L2*o+(13u=3?U|0EG|~)wi8vAg|_)lu#xK9h8iw1>5be6Hph#zI07 zvPFtQN_jr=yN~XQfDXM}RjbA0#4bEy?IuW-Yco603a>@=yb1b*EE=;ps{{SIfwY*L zm)9Ca%nL>JK%EV)gJw3&>}E-RuBRB2?59E^i~8D`he>aBPx^E$=eK`ly&-vKFmg?Pzw}Nv+++NebPu72yV2 zXgfMWX5?X*1n$!orjM5;3lgr$6Hk6p+_~0q`7*JAyOr;{Ml?0hRFjs7UEYM|x|$iE z6eqK*@Z#Y8zIB9EpBa;a?uU`+$$5guL0a@gM(KdWnHv?L;LylP9N= zvfno}(d5bD>nsa7kF&BN8*}g!>~6*~Lb~|cHu8+zz}}%FO)MP#w2`@)26f|q@zOs} zHeJ*}I*BNGectjt6;rfc-8O6PpM2EZY-26#N0lv_)hKUd`BFaKdL<$&U}zHacocDe zUOwcQ=l>+!ZtDW!UdlQmY^s(ZY}y-PWnZz69^=zlDZ6aE`GrxmskF75&hKme7~}>y z*TuH@WPCnmHq_)qc=)rKWwr>m7m(jv&1I;XCEQ;dpAf5fqF@Erytf7udaKVVB>!fT z(J*94(vQ|gV#QjMw^rbwcWOZaS0*Q!s`UFx?5In9k^rIG#Yp${ke~mwvQXP@JWGgm zQ+`NydsJVcr;RO#p)O^x0y1fnoJ8+mle-Dh5GGH~1C^Vvxp9xV?f4JxS00bwXdQTCXdM{GaQJ*- zoZj`P{h&V)tNfe#d~PnQtr!scL#P77&I?D z2=40b7m@&0YhE2AWDiKV{elYe$X~4`9h1aQA!1f66cGR~nszEZyV2I|zxcW+>h(y; zgx#yY*1whaU2-&mU84#Vy`!?Zj+`MOPu7(cbNyl_#&oAYR{EJnYw&%+X|4KS94HNe~z~X$D}`NbUHTr=GATcE&6wa36fHP z3|s{Srwhi((nJz&8m?1G=l{^jhV-JOXXGVNR1KkteNLHcuY!-cJ$8>dtdYP0AA4W3 z8*-mhM19T4EN?lDxZ}gMSZy-hU!^85X?R3(^lGDxBz}1lwMV#1+LQg_)ClG30OO6Nu9gS;3>tb6JXAc>R|IPsyOkY$PC?oi4dHbnd7({v{8&2?or zq6-S;jTwgxr& zOIQj)mHUFHyG;4a>;b4p)OJeBL#Z((!J9Iq3>KDH>wc(cS_9*Ik|4`;oXdwR6$*V5Mq zgTSqcw<9n`$G5lQ9C`nxlWu7&Gslddl+T~Log_(P0CI8^gj5!N zaB}4iv36}2xrC8!fH0Cm{}IXmS7GgbrZ+AkNP8xRo!U$&pl3V*EZ0=TpDyD%`QIm1 z;@!asP~NSHn%spVqf0!?Cg^H6BmjwQGL3b9&1U5$4#nwpJ$46mq$Cz~^NDg9zPQ}+ zMOqS>PX04Y+^0cHv4B{At^Em# z;ruf9^Mx^^->Ka(81k! zIjzscQfU+FL?p8cEhK)VL!m8TGO`yqpNS8~V~AO~wx`5PEq{!1Er;#RxF)(qC}#^Q z^Ylfjs~f&#ZbndeucKvxPX(A|`cxI~^}t@QBa*m{r5>8Da+{`Y$HTTb)c>f6<+U44>mjxSt0G`}^TNXuh2=tUq6B6VS!n*kZ)z}1OkVj5C|yxu0OqG4S!EGyioD(7 zx`SfT82aj|%ycdUhh!&BhWmCayTlM#o25ICRWz#i{uHnE+|1AGaJmm(#u2SH7g|55 zgQ}=HYE7##Q$$*{Tez-i)$w)8>6&=T=~zRvT*a(-?m^N)*@+-x)QeMHL|fo zI1s2MxN2L@9uwqmCg1;E;Y|QRi;Rb`Dca#)08#)druh2RY9+7xzAmX($ZPswCP~b# zKpo7}5(#;Z$eCVhaLTp$dQ=O?u}k2K=K;@HXF`sz_+||Aq+DZ2$ZuR%caiCk2?$^~ zro>&>$f=MVLkWri(#@PeB>xKWC{#8HF6s=bWySyvQVvb0WSp4b3@J>;udG7zMcKq= z8oloH5KjNc`{EU(u$Ypt=uR6gKy%l4`dLz*5Qbjvhb~R!EOPri2Ipeq%E?HTg^rXC z5A{_IL5}{l*t7SOA^h}!^Kg$w?-*Okf3;7Oi#F76Vkkh4tR)a>T=zN(ql3p->71%< z5;+;xa;iv5*1MJFInl9)4Zui)`8}}YxTNJFwR(b%UvqPnCIqq->H_T z_r;Iaq&6!}SPxC`7vRS$WN>npUA1P+xA!woMTnHr8m2)-(Y@QNmzgRm5PKz6f2*cC zi=SD}51A4PiR)FL6hB1fZ&r^d#F^R`g*zu?`Sj-Ho7HkK3H^Qfc#f55fHL#(pqMnl zg+GcY7Wd{{0i5g<%Jy4JWu|@iga_tNoFFR)`sK!%G+Bs@x?7@uQ8=-1q?TB{dZ$ z+#QqBveuX0sI&cX^K(p!UF)neyfdBiM$aKK+F~(zd8IzLtM^o0^IqqHm)FovO`CCH2$?wfWlOOggJ%Ly<7>%62U4|^H z3T@8j&rg#UHE#4inBne(AA_Cf_(Qp$o1!{m*p1ghcGa)EkAJN>(Z6K;(enCvml+Zm ziG@xAuZ5p0_J^w7h74^MyDs7PkalMpi5CI%qB58R-x|4e5BfE(pSM7s8>7?Ph3l*Y zA#3g;mYVDDL>-86oPt-n2Q@6a2ojGw%w_}pR?U%mj_;AmiOC;(`TbVl(?Orc?`g`X z&>MpGP*mtJvv>p+ouv8Uxi~YJoH4r(gHoaw&Z}u9MfY!CO1zB3@HIsC+BNgMb(dhP zp`9TeJvZd)erwd=XPKoDAni56h`HqwXMKNtSML9y^y7C6-5Lf81P%VJOR7O=V~scq ze9eFv0u;?GR{qB|dhEM(le~MZ`gL$hqHX>nK4f;|8}bWj(rTYK+7|jh_zrC|zK)u^ zw;0z=-}vq_hO*wrZ2olgVK;CT2s1#wUv-2vla6(!Omts6i4H>vZey>^9bfY|3;pO) zGed=lffaP7zvaud&q~{ejX+gwGz;`E5UMMkUq6p@q1X8Bk3 zd;ImaFREc5E-QRnZ@VI0bGPa@-{{YM0Io>Bq@Gvt&ch$eDtv$)+ ztoQnHRe!Xku;6|KwfA=Ssx+dp-#g5#ahr*<`&+Hz=myI2I90gt`aZ;Ozw$2K=wQCi z72{yOy3eB7y6@1aW{EF#q0XGOY@s4Hsfp!7e1USFaqFE%y5oY{_rLaq<^`~+f+JJJ zoGo3g?LwmdTU)s@eRrrs>#at88)}i(owDZHS?Kv82JM7W{?M3fzM@8WT)FB=vT@rd zSi4Ef^;L;un-Z;``qws_N4yKTKrqYuOa8)RubAT?;#v@ z#E&At^1_BQmJ5$dHVc1!VYbeu*+Z92bq6Ol23H3c4zRtpX{}!Z3w0}B&1h%Z(~T|` zYQEI(ndtZ$S#a_uM9(Z-(n3KP_~UiH7zy@s%_bC&%bsJ?CSlPH^N#}di;d}j9p>Kc z)g3@Dgs;XBKd3&Blqx{(`z0qwu|$*+Q!u%$m2#+vc-#Ft=X{G9XC~M;(*5vmh_82M zvIuVelgwAxf57vA$m1)ofxgYHtOsOGs%Lq}hg5=qj!Y^w((`MVQ9rP22dN5{(5fO$ ztXhA4I3FunaHMnOQNjCe=Bx^@z0XoY zu1$0I2Zs9MXVZU&y9kd3l0ScK_j<^D16b?3w)a28&NcZ>gg5-!E@LYl0#U$O^9Lkw zQ!4K_YmWGPLAx79VUE}7$czYR*pqB-7dm{=a1G7KfH&!|q&*pNdH1!AvL;T9wjvF2 zWw2W%UTD1HufHT#kw{~w1*;UM@lZ4hOXlGJ0x@iDGV-4W=25bt7T7*UGCG7DaOzq1R|QaB@*W zQ_Fb2P_`_o`BH>=Vpv~k`P^OaHT2`lg_mK`;u3u?=PK*lPV()9XQpxCDMrMX4il}N zs!1oENjb_)-5HC1;?0;4_i>9ahfu0z5vd!So(cO4<;g!<1mmv~RVMx$RBN#v^+SPS zOG%j(JnhsfaqXyNrM=+*aXRZa&gIa4eN_v4fIZN4PV0mlzmz=qa&ql4)3`n*^fXss zX<0Dpx^mGk#Jl@lfSAqXclX;*=Ol`eOOCffk|QL+`E;e2W@@<|I0Ip^IBapjNBqqz zj>?yR%A|Btow3g3laEo6!6*w~Oa=CVQrQk^-=xoqPb;i$C=ffAYS<#`)J3r@fRnY<_$hy>2MH4tyt^W3i`-WBq6 z5gqfqWEg8aOhkpa=C|+m4$AF5EsMz~w^GU`x4K-fw`*UX5;pDUZ}9Kyj?5dG7`Ncx zh*!<-c;MG;cm#~5r!T~Ozx(O&*686@jPk9^8|Ge6#eFH=7p%CW2pI-KrT^9mkvAK8 z^#X=8@XL>Rz;?&1ixETB*c2a!K1lQ(R^plnmi~F!9y9l5nHpiv(qi>jXV$XindJqa z*W)!RWH`x$K(jxw;A9gGzN#Z@h_T4%glmHHaBsPhtYb$^keM;L#%K*OIZ1@fy*h(O z^!epHd4EKHxElz8$j0748uu=?qDPvq%Q2ew$8Q>Eu#Kvons3(K8tRXp>TW(NkL=c# zqF=s(ZlPCzklQVh596h9S{8h9c6&coe?G2oP9XOe%srB2h-ItzZ>ys;Sd}x_a4m;i z@9=9;ONMlqMaKRuv4cfD{u(Cae3Ad%D7netlypPs`>VJr4udf9w)5CIqD!FGEiD!r zVU`kMqJ3k=BYEA&I^ykZv{GdrB5BN)QE#`l@8&wY6(AcA8b%j;?~;wiGr5{u`eg5P z(B`(Lxs1O0#7=WncFbD9oc%QfC|{eRF*8$#U*E;bGht^0(_)ShLK(4z>Dk}VM8+}+ zr9@0=!7`BWMfW3~E?M9Ho*aDV)xH<+;YjQse3Oz$!2vZl)QV_zD@|gp*I+T>3?**b zJ@VvCFQ2TK`&wXw-B*m&Y|p`?K?fld&+6s zTj9iV!T3S{+v*`p*^DLUtLoyX?;;wU3=6E=1-|FJS}>u^-e@W%XP)&OMxyZj|1AsR zkNuTCLNrld8=1_0B7>eWrrf7(1$OdRFAC1mX5pq_0xaInc-5?e@Rm8Ith33K>Galb z883+sKPcyfX!&NcVEv80nwsgI?h;9~H_Tmd5T0@qEnw|bd^3{q)yjue9I zd!%1!rX+qvnic1MB&Cl3STxpQ<^T>hfET&l-m#7U@jQw(M z`vXX-lj9pD(^9G-j^N0>y|<9ayFLSx>STOr9uDVE zFyoE0H2325Ime)=$d1HL&0U)m@t?CGdrE#(tTSGskr%y>%ZLMq27_*d*xu zv}o<2^fRRU8;U?usRX$+Wp#zrrANf35AfM^c?U!{>O4e!dSr-Yy+MJv%a-NjxKgT? zAz!IZx7Dl1kB_P@3^=L|op6usFw#Jysud^WGNpH?=DtpJGN=XrZ>J{>lUm}SPT`eHA0?f&=O(W?2Zc2ObXbA23;3}Ppya~v}H9==r*B6SR3e=Z)Z?%Y5c zX5*=E&q>52!FoPHe9ib?m+6#=Rf3i8Rrq!}r9!Qjm^>ban5@!Y<)6IHSP5xqk`#Ir zHrb_-t~I6?x;8><=!oV9B732#l&TR6k5_kqocb*QRZ0`_tXi-f$xyJJf#u`SkJS0B zb|AZDD=RCzLjcX|&gbc3EzNvIQkxl=QQeg`%rLdgzS?T^S8y;Iy5g}HAfQHMEMgQW zXR0r!&#H)XadC|pS^D_2oc4bI@dHoa>Ifl& zS#t?g!_>!}v!fJZBT-XKFOL^z#=P{Q9fV2k=DA`nF2Es?O#Z^>9 zFGy+~mh?M8e*pzhp;QR=VO=Kx=Hdeb3$^z1xK!&q1LTkY8$fbvoyxV)W4;Q~vsX#qnQ4?k;bkp%|@xNpugFKJVUoh|<_3wc>|51sF`}JPoD~Bw4s<;+;^7;8h4$mMcoz# zo(D+ZI=r`c3$lMXEHxF`2Y>^F@|BXcY0^GZEv$8iX=Sd3f1N=RzFPW13y4ij5Pb8% zBN3hUd-#`69z9=Uoi~Uv)(E5mo^3<7J&0wqGLSMw)%J>9_L|{) zZKIQy54LcK-Tz_htplR$x_;rIJ0zq_5Re8zlpI0{k&u)|8tEK*Xi-8WMOwO5x9b8M-?>8{hkWpXZ$K^H0T#EB9XOS4;S+(vMSw=0a+W@%&D8ntJ4Ihs&UWOpd7l z6p5X14(HK%oyuv#e14jKE4=$ONqwm+n$q3&SLugfF2e^B4iL|%;M$)+7pEA4P2|ea zppZhz+*{|e)Z}B~dWGh#S8X@;ob<77(epeMm_)1@SYc2b!w5s7RWOR#5J*Hcp``=i zfx$7}ew#m#A!~iLde)t7lhc#%@8`lV!Q+;JF5!%+{GS&@C#5dCb+1CvLO~TiaNR1Z z`I9*Id8gFiaB3OBn!PNU!_?Q*1~og`6$7d~Gik3JjBd{&ww?{op9O;vk}AysMbHAW z%?eK}5>i+K#EM71O3?u$4M_H!C=7#62nZQ@A%wfXWrmHHVGAek2ybL}RW3_U?1ppk zRt7WYuNaRps@mpH(@ag4(}zXuCj=<_s%%HtxpYdYn=kkKx0hU0;du_zHJ0L5z>nb$ z815l(jkD8W0FwfxvZeK1Iarqjkep7+W`G5z4F0Y>+1MwtSi2m(Rov%Rd2h{sHjc-krwcT#cd-8JmZ+Y_E#!Z6#6OKC%;`xY&msp^ z(YeZb)cO&pO8jrH?1>2*u}qmNhZA;M=~n^_Q4Od_a&ou#Pxx(AJrpQ%1^ekVKnSgZ zM*~O^`|ACM`I5_|#g9uyfPfTZ;R#3^=V%5pMEu=Kq>LMQ(?>u=7$tmR4D%Lx*cKR6 zp;5u1k^;rTr^x!G5NiddJ=%eB?leb_xL$n8-On&%kbtQN(Un@{z3Pr(z(-%3)-bW3 zZULT!2OrTGB+Nm+_0=c{pGvf#xe#`k(h9nR>+SgiPVBk~oDD_{IKE)iyH?{+K@-st zR_Nk*nSS;2D`FDnIc)xWl6Y>hjFJfjYQ{Z(*!TY}5bnrwsAXu84DOD$&j-Czfy>{~ z$OYS4Ho5EXtco~!9kwsr9MIJtlMmPL=iEzlO3O?o;(6R!{!y7jl_4+mD_+9;geQA0 zd+wXx%u+v>@{ciH3W#K$5|&M#+|RSlpDHGhErH08_DQ)c%AXvAq+Ns@iKINRXSg|C ztR$PD09UH}$Qokro`nHDm@tnW0`tXl;i?~mEJr=t$n2SbOxP#dnWyOqbrK%~3gQg0 zudIZlG2;(Z^b?{?SBe37FBfL+9Z!R>o&1s)Ty?6#O5dMSdrJWPGtzIT=^#do7~94J ztTrVG!MSkr+x*6x0Y*9Uc!_YDcTu%0c>5q!dS(S5@gFwxWhf4bU++up5U3(M6x9CD z*}w*aXN-?}RqA?|Y%mz6&C-Zy8c5UaDoGoy63b5JBO+LvAA?0a%2Nt*bS{5pjCUX#_ zy(3bP2;>mYEtWAlKA#Se_9iZPhvfbw#bDs^2e3O~cO{D!(Gh%=%qgUnEXt&lya2Yh zSlkNxD2OI>j>a9Q)RTz&?-uit0>zf_pT*-z4{OI<&U?Za%krLZV)i3AIVHDN?znQR zDwE&g?Zk3Fs>E_P%CYr*fojG*+G@rlS`ntbJ7ep<(qo%${LzMp*Q(#92h%a2=vnZ) zoeOBe%WZn;`08kQ-U~|iK>&0$5w;q2DXJ#m$|tdq8WB9-iLb49Oh3nS`gsfN54x)m zMEmf3PaFo?CbIe#ikXcdgR>_)q)BL3#mvm0Js9h25FM_WSr|U$bK^%%7LV40zxBY& z3i-!L!r8uw@c=^NJ=q2n$2*kziHzP8h7xTScYHXJzy=Vk=V1}tuIm>us3*Ai#E=o% z(Dt;zZFL}j=hHK|Qr#2Kt_1(nRlVVC7oj8>(L3ui>BUrJBYXU2Ip8*}*)T22&oQTo zMI34kRG3=LJ|0{K$CAZ5WnzhbMHH02<+vgnyZ53`iv<1eZ!*{kWwBM$XoO?`Im9ZP zxWssz`Dn3_5jVDj`iUMX*`Gxd>i5(bT5WWBt}A`pTkwaw%Swuh>SpSST0eHsvQ#pq zj8@*uyflMNLU(6mo&)d_r)0b*I%M2O@0PIZvLe>IcUm+M;PK(ZvN=IlL87}l_Y<^yVH*UL_ljsIkuTjB zF(-M!DYlL4Fx~k6!S;D#&5p@qP_-3-z7^lw38If=3D*8F@vbfRU6ysX7Q@`o%Gtgg^)q#H|0?t=sU4OLCJArv;N9W7|J=E6cndnP!tjy`>Hj|D zx62^hGs+c7Z_s0q23Zs9JPY?tyNssnu8O|y1Xl_)A;m6*yqqD@#~Z2 z7jWjdgfx1*v`0f<6~Fzv2;2$#=9bc=RrLJ(s*uG#2RIZ|!9rn^2A`iHu7_$;=}i=# zBpIQ(tqTAj{`V_U?5)VVbAv`Cz7xfPS}$~j4b$Aow7@~VmcJ9H@$Y6_icAl|v4?Hk z{G}oVq1j_@zj4zr?zkRZJjAU?`4+{0aHH3h`>VTho^0RM--4gyJSltk;V<;QzPn`{qK>j-2L}C z4yB5`O7cPQ0VR)nIQX0+(ThQ4TCzjU!^%r`#u^A$wbBv0o7*)US$E}*TxJ*Z_zlUk zO3QOwy`N|PI0yG%RPGkPst#Tq05!mG%{rWM8!XyMW(qi!5tCa^_QMhrw2m2CJTfob z*;Fe!_~BK!%1>GNCnwgnZ~Z~lH9|rx-cMOfm+g(|zo)ggxMHz~_nyTJ` zv1~#jnw`%~FJw zE+B#98_C>Ce{%8wDYzqXChwW><%2+N6`zrz{B%4(&BI4ph3K3r+nZbAxxEU{+C8`7 z=Oear#kWRZcDRjN58+fDp~(8a#A&Vq&2PR;2=-805XS5SyHQRMPGqund3InnlniD$ zR5>rmPSrSk?7jl?1)i`ziOPCI$vq5&l1W`y)kg zeP?Z?KvPyWn9F>*CvMw3Dm&%l1BV=7_rob=Qp=D~0wKitI%WDp0P$IoOHlatHfE5v z99ELy5eDA8gNn-~0vhq^#v05kn5eXZo4V1~j zVqV*uF4Ap@22RZ)bcB(Sk=dX!dH(t3_Zfc(D2?g1=37n5GTw~q8hKF8!j_`fcR;C> zK+GVPyNz>pu{RXxZC0p0e=$|AQYN`pRNm+K>l|=GZ_;`1v@+)G~Pw~230l-l&Gv& zuyZ~Gcd1s=^Tvd94(z>SM`SCKH!t^6y4OFo9$#TB95y|X2DN>w(~lA^D6{ccLNLY5)$JYj0^G&J=Y*VB>{zI=a$Uz$rA z-wO{mh1@SU8M}{U13rKSiL0$WTlQ#uOmi0dKVzL2^yYU4U0*5pV%O>=gW%*5*D`{%IX*>E+ zgU80N!{Mj=-k4%_1#OME^)8#ZS?kF55Um1LhV#X@{L3K;ICmjWZYqGkHwI1YPTVuI z;J14?6>4#u>aOVS#PqYW9^%qUL>E#|H)?qEjWniheiz3bF7=rSyB*=Cezv2&+U+)d zBUYVRLw}km#dIv-@!^U%U7~T&(;vANJi`MQEzv1^K8Zmj-?- z%beivzNeUAz&8IZCyjzb&iJcUw0k(GDY!Q|OR?&iy&{Fiu^qxL0aRk%>ksqpS`SZt z#iO92Q`pBYMzJXdLp?_B<1-I}RD<8*A?dXOsVTjNWY z)t~M)SLC|W1e$5C($`@Ec_8)vW4>y7F*7NIAk_Juy~1-dn~qRC_ihHS!d*@yh;$*w zYF3bX06-aRW*a>4v%vr4-#+=V@x#t@JV+<>?BHd z_Lk4xK3_7(U##Y4$L&zwpJnU2XSPBg)eI0bCF|GdTmYvOT;n-noJ;EyZAecgzUeV9 zf>a+f736-Sz;Y!UWFLu)SFriD6SCI75LUGIEvL$LTv&NfrAC_y_SFwe3eu`~wM-Q> z5BC+9{lFM-YL@65j+GUx&I)uQSTHZb{}(Zn)aG3HK3cf5RN6Q`ikU^Q$+^@5+x>D65#)8N&v!XaVbm9*qgYqk zkB_P;YFA1YP~)A<@62I4vA31;88y_^vPhFQ73!h8@0Vk?{pDuB#-3C8-cK~r zRT=D(y5=O=Y3+w;6q3fl}GOXK(}!Hi44CiopOgscGLv&#mWk4<8r`3DA5#l6b)_wZPBAsjtJ=6R~= zV)vMHI}<^jSwb&1mn0rhDqH@J8#nd7bxiPm+}cIAtnJ;G`)tbxGK&^!9-`#3<<3$X zbMX-Bzf9##O{epIhh0Mzw`79(mQa-L+O0_RyW&usY-PnugX^n(t>V#st(p$HL;V%; zq93c{&u1B9HQ#1es2^nCE$T&B7a9LiDAdXHwMETfyWjC_-SS~h!>_l5un7#@QpVIn zLwt3bm#X%mkg%>K!ggZd87Ha$5kuE{D}4*#ot=~&lsJe&=k19P8T-f#p@p3jGKgt4 zciFkX{5K~)+k42U(uWE2*5WR)LkPsRAv*%UFG3%tDE2`}+4)RU^ zO6U)s(%dkqgJmNNiglwB9p3Ysi534@DsT4Ku*Bs?r3CU0d6FgKc%?W_#1{;AWb}S7 zM`q#Jhhm+p1mz^2$7<4=DYX6i4Vc;jlZRwpGnSb zie~6iF95k`qyxplOM8K91aixZ_6=qCt(Gwx0M?agO`7~xK+s4}l>vc+_h}1vwXM4S zjR9Oer-=hi;IH)Oriw59yB3nNzoPc)`NT?wr4KriCdtYUilmit5Z%$2yuTd(xaid? zBN#g4D0a*LUCow((#I2?0tOtNp*T%nPHyfI7fA>^k_O{c0Jdvd%Q8qnkcl=&yhCpE zQPjz^6-SNnI7;UA=>AIo*gP(s94A>Dp*vtJj;2s$=xBOTOwx1U!H5bmr=FKT7Z&1GL`wPoCOhBOdYBy>)OumcLL>k)xu|P_&s!&IpiEMqepDSDQA+WhMcX+|y#Mc$Q^&_M z5S*L)OR{JnEI957xpp$Q3y`he5dLicQw{v@D^8(oW@`~8TKXJ3=ck_V81U-T{8KUf z=V!RK=9&$nt8XlLT!+eR_(?z`CV$7|=2)ubm|}Xr_}^35Zs8@@EX@?CWhRL?M|DaB zO0sTE5dcC^85py5%!&TIk#A3cFo62}?afk)hlgm-r6tFA!UnvJ(|VdGJM#q2#l?MF z5_y`8=WK8*;52g zMwSJ(+;$(woG3#K^p^j$oj3PI7TsN-==T>1nq`aqy-pJ8QzAli4QvaMdqfevT3P39 zrE0FUs3=+yF4XEC&J)aHLZ`m6C4^nn!?k$R==qt;vmZ)X6VT#S{v>#95hEl0>NFlw}hKk`B^e(w>jR=Z1jJ_p`JS)a#9f!nBT3 ztTRNG7l5bLQ?HsKQ3Ue4K=7MVI1hd#;5I^+_4FGYC_FyshWqevK5gBme&%AWrrGg< zP0VGHjX~^7Yz@|dpj4qYvk#iBI}lG`{{XsgxeViR2%`V&lMcYUZMq#g7@O~*C8 z?lZ|imvMaJImC&Um3s3H^@8Eo z#ZlKaa;axFkMXWWfW=*iV8u^ya84%7Al@X|v>Qtcas% zIO~TaG^ftbp6k&LP148TU(H#ivF%%sT&z2MyEfzqoVH*uFz+0>_AD1yv)Zej(TYQAW53y(;09>1*!g6yI=M4 z%HB@+)cgEPpy0XxEIO@7>s@U+XF6>#T4C}W1W z7oTi?+d#F)hEA%GC4OFRZi-3kvIQ+*{?5yPM0<3fxPkKd>s^>MkjB@%BD?_b$lC5g z=V-PZjwK+pKLOcB$%)mE6dCJ*wCqT7j_1jIMl;;(E=F6_91!6D8vL<3ZiJ{68XabryLH&NUB&pgPiL1V7lS#8K z2P+7+$I!{q1G7UNr;K;Bt>0j-)=59c>MCB4nFmgR+dV!uaIG^wyQ!Z&_+x5Y*l>^# z1uH2TI}+aTYV=qYy82Lxb7z@LJ=2U2XQ{`4=@Cu$-1^ItsmU`xpW>3qy_T6*P0_mI z{)-jpSngm8@6ipTMO~h*dX1WHVracu-WqjZj2HGbGEr8RdP;Lo-uk7c&DL+r!&y|{ zsN*Tl;cC~4u%9FOdG6pdt?EC#qo(pKse1})fC)L!Cs9eg8M^8N#(QbWI@f@X?!D0c z`v;pxT_-Yy&8>n?45tie98tKETosLFz%{#cxm&6##~L&^-OQrlu`uwB5mYN&D$r zi*L5z4}6;E{0^Q?wfb5iC-tB;Jk~#>*k8Idk2XY|W z?=?AtF;HV;>pngW0iM#}dT1$mvX=U-CzSsCwx^Db6$kn?kLwxHae&)?vmxfB=@bSH zRB1C5UH4oR{;s?{{EmvSISs~k-#yiN6Z7a<#I+Q3qlV|xJp!NM)B1Fq-c0G|$wf@h zS2D(jx|<_6Nm$1Vsh5uS$xtxlyR1Xox)w;>Iur?6_G zM;$Ha>)hv{iPLUf5BJQnzl?6U>FWCEa4OIaA-)Kb-Cqml$am@>RM;M-bN(OPP{D{-5k4{u;-0wxK+!$AyZ&+fran=fV0#RR<%doLYP-#M z(TU_~F28T@4hY{|;)I%CE%dWA$ur%Xu9#vP{}x ze^kM^v_EIMGPVsC}NtH?C3Eaxy~F>Y)*t*lY{tu;Qao*^e3^ zUZf2Ns86w67a)UdOr9y;QDyNKS!ajjA25Vd!*a0>gy}WLhWz{}Iw%}P5bq920J$BC zG!l;?yZ}=y|1oRb+uKKOu|8TP>^SpqW$ZIx?p9d7xUMKu7LPP|ygEt`*WQ2_s(S)4 z(5wfic5wpwT{sp%Y}6}*2MG*7R9-P_TPOHkYXMBt9%$H!{3ga%)Oeg-7unk&Mo051 zcpQizTu-Pl`Dx1gH!51oTS_#j(#W%)`53AH208nq7dES!YLY8bo~OGD`OZrqL{sAk z{dBSAiFAAaciiMC^iuEhwSpoLm$K~u(30nED?qp5;S{1v*5pZTtX=f{u?&NnnCtRu zyTKDc0>y6GY=Af+-q^<`tQ3S-mWR8&Z~vAMi*Vx5Ue49_-QV@MUJISRl>{clR%i2% zAH1LPylL34*k+zKWU^lZWrCB(4cOX8kiYNIBCGxs=?=(OUC+QsirsaHGM4d9z? zz+lSv!C=hh$ENbUy5RJm+44Lu?Ek5i*YBX!awT&3;v`tu(w4&jigRKMGco;gx%qXF zYlPzv0fGj#GAO8Bw;;q22qnLEAwd1MaIny7Z0f=ztFVB$}-y@N}tPGZhJ-Iw-{qqc93R)1nZ1WqSoX)W>Na_@cq2C1i zyuU2-(iF;4j?wg#RH({sjLUAcFm7LX;h+Oj3UPx(-z0F*ihGt$5f8E&J!FDX&*3z+ zw@i>Myy9dUEQLkqwt!%~4|Mr$2jLs&bwLL=q987nVu0~(`ylI)1L8Yca}Pk0hAsk= zIV|?Oml!fp19dQ*_tbj&7{HLvfsCdp1`Bpb!KNHzvx| zUgCJdd|iJnn1eV#9n*brPxq_U&p^0zQ~^NA#MR30*#F&WZ{fMS@AW-Z?Vw3ZYB$*g zVrkX*zV$^V(d6$Lyz~v2E?*3sJls=Tzw?ZC*wX#%3afDV!U}Zg(>Hr-sai0N>k9b5 zyXpnyyB%lU#1Sq&W$A};BQBe{e4gd$@eTTD3?@4w8St12|HY>a|FfoRfi*pMernj- zp8!$N>{MXq|L3W;@2o15XLAOZdqb)e3MP{1bi%|neyq%O@iS4YWlKcs^Hubr*~P~q z`;8LR$bi>K?&En4S=XqobCgnCoU}sbXy;Q*BsTV7@<+!8r7LPo1Vmi`(Cm}}7;TUW zDp(g#j3hX=oLQZ?2plpY!!>&5(NoMQnp_UIKtBv`Klu%Sc}gurYo_`G2+?|Ha5rAZ z>pEfxXJPlC^q*4bdqFMKjnv7Q4Ch2C8My~3;7pr0lCP7`wKJ}7i%T?)HpUBtEc+~`!~KL? z&>2eKdkjjRa5{&dcPteu#j^{Wbzox6GIM8P#IiQwbh_c2((Nzp)&Rce7sFyc$74sJ zt)hMEqev?OgM>zz^77yG&FQak#OMc*wv%Ro{YZY#K#mnvv=EKW7iK>MJ69LCte&!8 zV7QmA|D4|1>_2mfiq!OXh-a9rFP}U1S}ZfIj%pO;XEKkW ztQ{n-@jc)ophSFjE32npq88p@Em)dRGAb=kALDYLTetIUx>>_tEvaRmKF7I112{P- z?XvEh4T&DQBu}q>QWe$s9wUmt*{aA^Yq(A>_G*1Awe=ic?CJVq75z}DK)mqf^hZ?l z?LXOHc+2x^KN`z0)pA1t!Gyv^q0qCSE#xzUXlxK|pq?ru++6_~YOWE@7_XU^@do)o z98H<;2YUzu+wYYnQ_vgdQ*!HEF8S?#11Px0N?+nvOfd)poUnmQyEwNAu7~RpT#L_4 zGLFWatzDwSHHtGQ-eu7;!L)^g@Lr7MNZ^S105mxy3~f}nk-=z>eNMK^j6cys?jBOf z4nPd+_w{aKh%bzxKMcP{nrnDL?|lNQq$cA_EV14Fc5k!- zgyRi*l%a2E0&fHBy0N#%-UCA%wx~AIf3)s=--XQ~^ogdak_+RHYpZFacI#A8Ny{C|KBSvV zdK8}9*61v`;)0*TTvr)*#Ov{<0pa!Z<+TM;U&LdY$G-Pg-@ovis?V_MzHqDf-0+~q zuf`v=9&w5ZBlsc+8p(pYiB29E%_E!2#lzRc>jL>a(W&E6EheK$UHtZ+>^nM~Y%YVH zY+2bl<&tK9BxN< z?Vz~#Tz;i&2+I^6+6QN{g5o^#LIwrT@adEo0)_1Eq09vB@wgi?+HJHnvtB1y3$vCA z6`T@IoTShl(6F1{KMtij->4op?yn(YLI*=V<*lvJpY70a!ljm3QYEpZ8 z56JGbp2WKJy4^1Wfn}y(zI$c}tTA^wD&G2|?06|MW7nw7kp9acQ)Qjp`>X$uZr6jCfle%(s#D9hGn38b zp2xKf+Y%b%71@aqG1@e$=VJy&XFf0Y%Xa$XotESx(;Ixz#WszWx2E)>In?~gN(Tj! zLmGTHSUHv^42(97#lH>~q;IUPeckMD?i#6fIiEb%2KWo0^teZ%*57_u9qM$JpsKNx zH8)tChK4jRIPY_Z2nh|}1CUcrUcqy#C*kM5*TsTb2aVmR@2SZeXI-_!b&nhz&=?@N zp*74FZ-`hFaGy;zc$A>iLpb&FaKm>?(6R6lfL9*d+YOdUp=`q=+uQGx2f5WC9L0~G zunmX%HVswOS~&Q=b#x;(vFy2+Ik!0 z&rl{8@Xa1zC44j5yUcvn$m>Tr6wXqvF&>vyTFA51}L@^UGYV*l>q(0FB6>#)hNsHD2i_~R92@hb;RCeQPp-iOCJRDs(sJU3{2 ze4`5<;9Pv=y{V!8R?6Y3uT=6j3{@?qTHp8tnk2t}ACHo~t)Xv+omXIKTs5lFry{QK z;sce<$iT{Im6t7-@rsbo$y+*`Lp29`GzK=DE;h#A@JV2`wMJf%QBvkf2%JiW8khxF z_)eLAiLSg;D*L^|i=yqVF`vYs=&UByHiDr&iEe<4*>4yao(LYpg zrvg$%>NTZ=&tE8H-QQ7s=!Zv;G(CG~N(04gQ=n?Yl+Y)g!$JmoEi;7913#xE$+F zf+1*qyBuHsy|spobmk+ErW-PY7Dbpk{90M3HOjcc?d}oHpGV&_qdz4qyRSSBiWHrm zyl-tpel0&$XZ}cJih3+RnASYW$ zm7EQt0Wk2g)f-5+F?OhN=U8p{WA00Fw{2iKU;`)rE#G(~wY~L3@X11N2NEwUcq4e` z;qJgf0FYT|Y=y8$6T6P@D(k>GQB+d5uU_6QO$mE<7tU-%&3}FbUo&p03-Fm`NeDWp z3zSFa!C3A%ZNEn8UWw62+Cr=$-Uy}!1ixZ=*|-wPYA~`nY(^>PZw~>|r@&2$gQPpZ z|KEM$LroS*v-XaU&*yc^Q8yKaH_>nNzlBnWd=9V0V*gV)k)k&)e??d}{Uw3ci~m_{ zv)3&YkKv;rA)%4wj%JGFaOL+<`W`z25H zAC&!$D@Xdkn!x=yufO7|M`h|5=~sbH*#n&=!yl_FvWexmG*xD7m7n!G`=XdDa0yu| z@T|#gkHXKiYK;VawwD4myIGiq_D~qELmeu+zhrQ!3D4ljv!xPJyKs81O$Ul{^ikQ2 zJ41i|FZ3T1g=w-_#O}}dL+o+KDcBo>JU9QuW2>IOVgI@IBoffQ115w=GB$*Sfvg3J zI###0W@?kppV@$k0ONVH5x+*T#sfj=wEuq{w1Wl(Q-*Hweh_Zzj_My|)e=A$Tk4by zMh1)X1<$Ukc0aA`P-nf{B*FnF-cPWw$k)v8->v1aw8+&^*3Suj5eY0&|4nF6ltUvp zwsf9$np=`KIT`w7V0n4-&ad3_dhIzV#&0q-fJ; zu+iC4qdLZisweMcIeT879zaxk z@lK;1UF_akr2F~id_oEtzX{_V4a|QiEfxxnri3v$`D?|lSk8*r2xn|DdNE7Fk`A^+ zjtwhvUlps*v3&Q{aOSXaJ1XI3?>?-O)a+ePP*r$;{7g*fTFE~*(!Ub<@LHsw{M!X> ztpOTObHEHS1BHORPz}}2##LzR(NaAltZY1Jf#UktMbO|U3?}X@^PAH(Om6+3^Zjx$< z3`{M8Od?J+zzK#f_R#nwZDFf{gV48%x;cz`2DQ4h6n(KzJ&Hz&j2BcR_0^@Gj&^&o zLa`XxxED}R8?=!pcUSG|Q*!^6c~aeYUwoe}b=;nz>iLYy^g-`yt4f8Qa+h2a{d&V4C-vK1G*As2EFCo6=`IrC`)<^wlz~n6W`c;-*3T~B zoerlW5lfWDIv*R5MDC!Ejh}p^s@lcK?h=dhs8#yoru>RlP>fK7k5o_kfs4BeM&r1^%(mPUENqlv7H^}jW(gW4DDf*kiGDPaOKhBzWAeIj@pCJ4*Zjze`XSt> z1e9y>H*n_ES8I|;*V^~-@kNi{-WCRYK~{z}3Xy#X_}x$s6M)i0f~7?UpxXpz^;m$R ziR_^ltG|`8jFlCiOxYs^uJQv|NZeNr?c~wj{ixKQv#6*Zy}P?awvsmgec*~&6v9w` z-&ZHg!NEw0 zOajjGgd|Ngbaav$%3FR5=r_3EoAo>RS><=;`o^6>Iv@?GspN5p>7AV}Kr>hf(j+Mu z7#P0zlNWD&X?dIE zZRq=c>pEiSWT6JDb_Hmb!`;(vWLxC!S>%Pq&B}nI5IPUi|>c{u3FBK)RtFuL4-OjR>YKh7y@uq1WdB{X`nJoy^ zoc1L@0Nh*RDS5H^^$;PN}6e#if630c}o!@X= zHPeoo4pvvdxieb#dBZ17g64}4k6tA_^?`#j9v)syEH5y39ifI;Z9IGrhZJs%ojo-- zDW*3Ht&`IbpsZ7%02MZz5ad_9GI&g-OSZZmoHzDGjLD@|I8-&}JmDN% z>Q8aw5{Gh3l!RcuR5^2fwkd%;$PEj^z7~<%z4*%YrdHb{t%_Sc)1^E)J<;XT=!|oe z`}#CT5hAupnG?cbBr)(aiM!UVY|AgHbl@+-G{4uS-B{<}HN$5}GPivX=S_i|&#Q`p zrJr3Pd)JoLQFUX@1Kag!hxN6em#UmPZ=oi(#?#bQ(b7w!+?AsqsVda`dEC!IoW*i9 zmsgR|5=q;t|2lwH^u6cyq|z47=qKIc-=D@`t$s3IYRT0URIne%U?e4xIyJ3f5_%Fv zE#uUDl$1(Z0F<|pB29O-{0-xc{Wu_qHs`YU@84_T_JO?Z+388v@3`(U^p6(jaLAot z4p3a9AxQ(~G^z`_Fn>||2_zp5^WFRRHJc-R7^VDfS+$3-va>(ABC2b@=o}vA3(xu9 z-EHtIz1m^=!HKV-0-O(Kn-z$_fuk2{g65^jX}-m79+=&@_-PJ#$JLyq2TC@6e7L`T zqR!OxD={ukrqOFh$0J-_E#asC>xOo2tnP&!Ksp`qpMU6ooQabCv+E1E(pjk5t_^D2dI9LdbaGOY#Nf~ z0Ek)Zr%9Rt2dGtTr+p+kfJ3^>8%oHi1q{3i#j$*lPaK(kLemFGkXZi2vM<5qq!TcQ zYRx`J__nCO!Uh(+di-z2gsM7~yIz#|;@yvouG;Z)CX7VBsY+9GR7)&;nJOO_*DLWm z9e!d0)`TPP&6r0f|E>v9_e{zojVjR9{I}E^(@Tq&a*eJ7y8K^6_l#d?bLw91X~#j_ zAC~svcL}NQE@vb85esfvewRNpzFIB4iB&KXWZb3wBeZ${qq9M^n#tZ!d|d#H9qG1j z-L7gZSpGFYA}WaOZKi^=RI`yzfA>MlL~Qq$S+_@PZsO(>O7r?hiP|3l5*Ne?%AMb# zvUu)%h7Z+Nh0t7MhFYYpMi%ExhEaoWG+SLyGzUcq5MFtX`A)`7Vd4Hpku{}8&)z2S z<(K;#4At5CqfosVG3$FvvC_k=u@X756?$+A+~{@-n(+motIPw;Vlmz&knpR5jZB*q zHw$}?au>J$#zPH!yPDIcKwy!dkU+8W6Fv^-L%d^=OGw7v1QQ;z0ku%vD z)Nm<2b!K-00he1h7#EKbGrZMX>-@BVTWzzv`+iC~;#iuao_Krs5Ly%=NI#aG8( zaY?5Ww#j0@PWjOaWNE@yKd7sv*X#W+Jh9yC93keww5M}{wv4O;V*mPnE~AF3U|F~% z$}J(R2B`<9JjOIbOKpqCCnZK-hIiw4<^Ua8NyCp+k*8PDgNuMMcPyWAj6)^pimI$SknJ&1yZf)4%U6-@H z)aKwQ37=TQF*j;*I7y25UesUzqQ0eSD49}3)+1vE-95NjOp&=Ofq(ql0EScrnfcM% zGU=_Fum5aS+ZJG>nyI*Kro!~KOa&|4IkkXKEoy1VP6gKZ%adb4tO-$3Fxf&aEul1i zQhUzx#VhQyzs~eei&CcR;|FumTMvFsQpbdzZ(Jb#xk(u8$2UIJ&JNV49oHxNtr?WG ze6fpfg>tB`Ol^&;b8A6y;=k2}OxvEM$sGC)77Jf&P}wRUDcE*Icn#GlW7%kZZ?sjf zZ!Gfq@aK7L?ars|%;skpQ?>c?xA}8V@9)KIpk*BZy7v#O?H=In@fuzgJHK6A?XgX3yKJVbn$yAV-`ld zwbAZOp;poRwPrHrkU^|LGFU(sFP!+#`FJaZbDJOL5~cm|@I|mua;)!~ta#>$$ zJCc77i4GiUAz6k{`a|yXWJwpji<2E)XKZJTU~60`g>N4uC2P)xY8{(|8J5EQEpj^i zI!G69POcRcHr-c@5--$s+xSQ698A7gL|*vAC9$6XTD#WwN7l{|G44B@t1}>hur3j= zS)#sjYqA--GZyHXaSKwx=({P1HKF$`Raj#|y+J?<4V|SCii5;n3Tv*>t78YduKNS< z#--m(x|$AvWK!SHet)yQvY?5z>m|02_+FRG-inH_`YQHFNoeh<^uyWh9WExT73`d7 zPew+$|9Z=`D$66c>*1g6JbC>bYSTARxkf?fQQ}Iuw68C;3w3T*KoHsypT;8-dnKEm z!jMTG*x^_=kTHc?rq7si`rB=4nKO$fzp6En%Tov2W0l2}SThx`h$VLAE$b?GUdGzsdX|eXk1q4yqqa zJ?EsxB%!RT2UUhf7IXC^}?@xeBk zU0e(QiZ*+6>hTYY2{YynZuZF4NZ~B<*VOwJ{*eic)c*=W6fP!$;StBObYDc$Y-?bO$fupOr zx(HFsPNdA#COC%VY+s+yG!b2eeo>c(sqT5gbZ+1&xav1B<))$!xh5H?n_cOa0R@xM zO2RSeP?#?hNlKKOTOFzh++|%doH4{&%8AK1ftvNzOO@0$wZ<*_jsN+yU(j$+b2DMR z`p#tXucGCH90%(f;a2Ko`Y%tO#~ag$cE!>&41F@dis;u?xe-0_N(&trS$ z(aA;1C3+471+g&=j*8@mhw-W8e@-REtiXlMA$=LUJD>KbSY_OW

    PvZ5J9(+aTA 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 IYkTj107!B<_W%F@ diff --git a/doc/pics/quadedge.png b/doc/pics/quadedge.png deleted file mode 100644 index 2fc6c2bfcf7cde160b422bff8d365e23d767ba7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4679 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�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⪚&Px=2%1g37VrYk$BJjgWISjqJH@a)dyMhq#s@9S1 zbypof$l$CU*cE7$nAsb*e-*c1R^)vB{cU}uVFYHzL%&3Z%ZJkyXUzf`8@(65S~%@m zf306$(+}Pi4RqEOg`P@3^HRI)uT`+y#CFo?h`}FG;6_Bma>|wxo`Ll2um)h;S)35H z$E;HaKQivLcqfCm9#Jmt#gY(^?Y9~vEe1{~{`&E5NA!8oaX~J8Ym*^dQmc5R6nxl0 z^HmVv(wD_$gyDIvSC2yvE%Cz8Z}hFGsfhqW^L03?hQOvnU%}(!wgHi;sa^FQ*5u$A z5yuTD)f+8W>;a(^w>j_VB-|AaDBw0)pKX@ z`5Ib%Iz1h|B~^8>Y1!Ja^x@>`&H6BO<<1it|C=G)*rTC919r2^ZJG|=FP9#x@+bSn z{aZaV3B!p+nZw&?<)@_+i-8m7@q|$UM2`)`I@I zH}91g0as|=;70pKKME7RKpiw;osqQG{z|eE;w)fhW@nt@lU5+6rLog-cK?0`?xq0O z+JIn5l4cWJm&J;YtEQaPKj6~6e9XFlLUD-qGyI2GqTZIC#^#S1h>>-|IyXc+YbM<_ z2z&LL&ezw>*6k%e_F`&h&O?+ERUbwIS&A{R*My-LZsr>Bz#IM=mGGJFpw@y?GU{M_>NUr>l9c_O( z9?o$)P*xS&2so6A;3=DSl6p1;9q~@3nscY`8axe>o=0?TpV-6+JFT8Rr{L~0hXbk$ zM)+eclHX4}x`$o>*bZ`qOoBRe%tO;fzm&%GHz8h=yOa{nD(LQ*LYH);DEBFUdlBtU z0s%c{QAsNZNWp%S+ldXGU0T0fHI_1RNCo5 zDX`14P2)iUIZjUllZln&v~zPW*vITyYKmCaP2$WZlAV%gwR;ywrtZe&OlGAldWnty zyJ~!Y+xCaxYrSwK-H;dTXjjWn3IqjPPpb@qI8FUA6Uf-5px4@7+vGs(;Q2b0?8}*2 zbF+18q}~rf-Do44k(6Lvj@aKXs$v1W?I%M+X~1G2Wg9-~-pC47HNX)POVT9U;O?KfAB$j=1nIke`0war`{6Q$GEzi%OLp9~>wz zPETbkf&~7DOTBAfRUv$iU0l_*Iip;!sa?L*u&4w|U!b7so1ny;7*sWWsHwut~X9V1A9Je%r$=ZngdNZ+U1f<)qvW8$CK~glR#$ij54H6^hNo56BJJ zb48)aI}dV^$sDY@7n#30-au+5a%>(}{iOmo{IdN)w`b3!Ues~Dc{MIPqloc+WrLkg zRjO?7Ec7o>E&g2WPuu9tGctSe{PgGT%SP+VM-)1Q4Z}l?$IwIu8q>B$eLWjdwj@_c z<_8*h*=yKZye*Osyk%R10Yk-eihsHI5QbRe0#+BI25ga$QvYSO6wxpMurDb|; z9=^ttCLKHB-Y(K-Y;Wdee=)9IpODbxA;2}+C=Q)T2o$eJs;L$CDKtNSll?7t9esl^!Mia3!V)|D%0zGH zco(vsfbAFFZ@r@_ald0z?f=$e_{@OWX1TFW6o(Vc3pKVt>KebzcD>;vf}zckmg*7S|<2C;tjj~NK9 zEruoYuFj_c3`ZWqZeGTV$7bDk1=#KmoMkIL4GN5QlFcDwN^tq=H?JxQDEa~y_6*_I z=f0ZfozV?gl2UH@1)-eKO!1Q{E_c0#Un1I%H8FfOID71+PY688bsJm2%jZDSeJ5qh zeShK8X~Q~jERUh%yJQKQCg=SH7TTACqKxs~IW2QnM^g6dnyqbh@o#=9CE-%BY6}iG zuMLKtzT@YY-4gnZcm|7)3ZU@v?df3fCBz>oQuYnFou}3v!t>BSz0h!c78}mp-u-gp z9XaKJ36QUAaiEW$_pwlt?wsN`^=#OW4vGd}is}yju-3-J9+Q9GOjxneRiu|JB!tD; z^jgk;+_G)%>QQK$I%PGpB}{Moa`!EJxpV$D3>zKQCtXr(la8~W+F}i^gB*BU=V1kI z7l*P%e%GYLlvk2Nf4VR~&Op^^so}c?*txh))JHxQMPGz8_;E!Yu4rB?znQ*%($E6= zMt{rqYOH2hA(v-OZpBEGb4r@ni?bJih`Bz+il2_WY74)!x1A!GG0;^u_TimS!bl_={4bEwoS(8C)PVBJ#CM=$g{N@DCoB^s=>{D=C}TZS`~INqcJPxMkk1I-6^9OfsUP?-RT! ziyhtDg{O_1rX4Gfw`O=I3qrbfwFL+NbH@E>V1ZEqWN^zKdOD!+g^t~X$vVy5)t4l! z@}C~w4s%%FTs@oR+d)*ogs=B&Espd_b3PWfJv*m>A{&a9RG}IAHOX54dYR8AvZ!T@ zb~yjc_|p_Q;+MJimE9eC)%NsEQ}q@4YXdr+)lKcd%A*lGefs>nL8_I!+&hT`(E`|d zM13}u-HSjd%>%xEzm6X7r{&NrHlS+lzKWb;(lx(JBS zXL!=jGS@40X~~Je-p4VA4C>yL+JC@m^v8x6okPW$(17j+ZC;*xhBx4g#1m_>`**m%aSdpt-Y}jS( z>F(}ERuOt0>|py`!We4t$vj<_!Dg6-`FYbjM9om$6udnm%AtzvCq0GrQfu9kmCv+r~OS+1k44 zYfs+2CBxU&QGD$o@8flJ?W98!$JjeQ8>jz0zG~8ASzqs81dZ1f6`*2}-m{~@(Q>2M zLI2rG%0F7qR53Nx#_pth8g9itFM9)l!baOZDn&0g=@SWCZ7mek>L2o4!0A_wio#OxK9%S3cmbG?DvFCwWA z`AzJdOUq&QTr~sE&Yt2g(R0S6brTUs`|IN0Sr&~!@VNOKVR*Rvr%8PD!apC3c%V;z zBmxAjvv{@eK0qaqiI=2nKmGLLEJq)Qb;{IH;nSXd=7!s~#%*F56hEV<*5 z^7I3}^=Q7CrEFd%ToUC6Ue*)etDkrygeXVi6}3Q6g-=SaR%~sT9dnsYA(jrlRl-|n zv-I`NS>HOjR~JUCiPoKMK{o!GOg3cR(=5Q{f`@-4YX(KVXNh+0`P}g_7Y_DWC39oUuyf98NTt^M zIt)0NIBw)4xFmeP7aAxS(Qn#CJ2(f==_~`GfRr+vVyP z+#N0Xpd@|*eixHFQjmT}Vx`?2HQj1EGM;Q_8=)9*%b(LkCXXWzJW~!F`Cu-Dx zwRSCF@un5}u|4KW@>Y5cyEja8u{Kjs5Ku&lkmowDtUExOf3qKz2g^0!=ElOMW6n8TB&; zXtW$ow|zFq!AEz7TV-S@r^4nuB2qW7gHz^4`KTDksv~ptOqPCGk@OA9znfu)%#@Q5 zz;)c1PPWvhb6N^~ z)n`P|+{SAfKS7qkqp|aYR%i#yy$g{oC!6y+wt z6l1iNT9gt46&EMwjVUa?m*I1ET|re)0PDU_M@66|-jaKGgo9%R-A)r@ru6r2~+MR{L)0Nu#PlN5bo&}ZqkpNTK?LryZ$l-)kJ`TAB(78bOChts)EF{)BNb1 z#&hPD5OgG7*a?l`L0AJ2frUM>D!aeL_~i}9;0TQq$bTCLK0s5m)L6Dl7@A$D9F3qT zhSO-CpJrN@F2kL))81tF-fJw$v3=9$BUVPc#ONg4?W1AfOHsWu?eoelOqW#49a*%e~aj5#pvLR3CGW&QEN*G~|)%l?; z5HOsH1vS8LXUb2CrUd~4zVYf(ohnNFQ!T#{4y;qEXu%M4c2RcF1{e;0kb;Lp>27=8 z4GA~!e7hw+@~k$`0IQP-<@OF?lu2M}@u6L&4t*E{lW7j^Uy+Ufw5?=4)18-Q@}rr_ zpT3HY#Wn7%|JBqq-JmMp=18>_yO{j*9a>!I6DqXyi|oZRz;!}|Bn}t_5Gq0>^S)1G zQOV-cc%j`IQ^T(YOO_{6)#JdQ^7h2*OP50>#XJRx;x^wHNXLwlU3vz|e4umt-P+WX zVd^-?ZH7+J$mDGV&wDkF>YJ&D^L}~n{2HF^;+J-Uz z9Ub`>l7a;7|DU*)FVqw9HJ&hVK?h)8DOJ3iy9I!eJN7kz?NnV*g^V=@J<=ptHO-Z+ z;Gv{vd#L-{CC3EIk}k&C#oV!x9%#-nzJ314j?yFu72z8brU`Yst0?cPLJT&h^^FJj+z`eopUnh`20AW?(bDkS$1~!t)-d2g-dTxPKbKWqRg}4Znjyr%E$2!;0u45RKbt5s?5Xmwyx}y~I z-fi03^2{W=e;v*;7A+G-9vDL1u+y0L9#X#uiDT7}`$`NR1$k?(e8PAly*~yyc9$rX z4^Aip=v<7qKM8x)D|8-?UF^~f1Tw&OMpI*|DsgOVc=CIo^Pwuw$225nel}5&IsE~- z!(*gv6MFrT8{MB|+TPz~q}`=I2sFK~s$>D4UL>+dSO%ZlNzxZKdcq|r#`=Y`iZCBc z-mm;jq+6LD%x99*Kc$NPIV$6ZAC?2V?FwyaZB*eAQV;)8{cxcqsmYQ+3S=rK{A z=Y$nfKItIqzI+4g*coj#Q;(WNG-4?NWwi^y$1hX27gh+%?CqeRARfEdrE49@B|+n8 zi>fqw8|Ds5diyy+wCZi?ePIbC?_g>bA|ia_F;RKj+Ui`>7q^{-DTuOXURRk3J>sS? zoM@9O%vJqq-rnA~IuYmj%W`;l40Ej?#Y}jMl8*DwUm#n+1hz9K3~`6R5o}I{CZuz6nj4oPE1n(1k7WodNY3$mgRR5qGahU5n+BQs9@0Q^~SlzwC5&eFNEB`^%{!@!XP|KylyqZP9vSNwsA$ zNcGw&6kE=p6k%i~;-yg-@GwPT^&2f*k)r6dc80BEHv~p5T@mdI8@Mf%4>ySzD!6W?uvmPO+p z%Z~{M=ZffjF$TivNpgv6 zfO+-GqHxJM_ooG>FJlma z;zPXR(xe!&=gllXP-gauj6sN-%B>q$fIBx24Sc`@I8^sW7%n_=l0F6w4`P8s5LoBq z7vSiB;F)Eg2bw#%`cv7AmM;YzQ|CShujCKb78js zgYLtQwru+!XB#JHf8*_K7SSvdtUQEU6D+1brR0!f&F(?BAi77pvDsjk#zubXx`pE% zV;xQx?xx8z`cm5e@w+q){C=S8rq!U&V@~ksLx;bPi)XR-rMzFgUVW4tb4&CXA&*fc za~zrjbpSOSx6Q#|KBxmR|#b{FiMGfEYX;AbL^khN$&7=!q3 zr1h$2a&}8oPDwvg*le0>@LfJqsT4Y5VzZ9SPhrXY3M#e0A%mfanh}zDZVAmt31*Y* zHwB=mk2Gs!B6#hb9CrKDSZSA4fru2IYt9g?5rVfdbMX75OrNBbCSQl5_t$kFYQoIQYW4}*4ki8MYXRM#7%B5*Q6*d+;VW0^Yy5>O|^IjCRh$-w8RsIs27_<Jkho|2!4LfM|AKq-Pd1UMMf={Y;qBiAkb`}H!)K6ph?mSqR zM&Op`m|Kn&fw0Fm(;}=-k2;&X4$g<^*p01q3NJ6XSq$?NpH300n>=}1_c`t*_Nf1p zhje;87+dVe$}6#JZh_v^O$fJK6*rGNM&?JS=kB&Cgv%;Vb7PAa(pr|jmm)FXF6X%2 z14{Azk>!UJ>3);q_Nmm-LYa+p)H`iynLF-DF9(_3UabG3k$ci^zc*0lwYPCoP=OGt zpD{ZHgX?RXnnRaY1SjkIUsfINt7XLi#q`W*9;6Nf=}wUpaG!xbdxr*dyn}g2iMdz2 zhD{*(s?so{?UL%}#R1{Hck#R87&xOVk!RcZwmw?XK+%pi;Qzduk$jO4&sysyGu+Pd z9*xoe^#NZb!*S|G+Mj6lX63zB_ezVA-vNA$lWly$v4!wdI{Ebnd74ZaqZxABTvaPK zTBKL2MIFc8d+f`%l{-sCc!C`?UY`f=dR2uEH&BMhV@55T%~m>9=xp_p2ObbSvtu#hp#tgQlaE#e zVRys4@*FUBT~dJ~yo24#m=LEj+0(s5uBeOaz8p=@>vqV6D58h>&qaMM7Zv|SF@b9l zTygx%I=-KI?uwUu&!%Z*Qwfl$#G^H?tmrVV(aa=)JtEXM?*$+ryVoo^9T|fZ<<5`H zfdXygOUYeL>-d7J=6bM?KGvgId4)#IlxDjhDJys0EqiqBr0_j$M_gN3KW&Ck>(`t| zznb-XVYeAsajiUK83j42kdQTe7qf(UG6paeKtaqa;-~ z{bkhCP1SDus1fJUqw)&Og2DsCxDWNK$^BS*X0DK=n(RKGxE$E&Jh0}cHON04YCz1Q z$KuxB)0T%&Z4#%*aU`<+SPo%=;?!VxAo09TA8C3TMV3;VJPYm93k#kkx&RVDOFGAr z*fDso*-!G_`Z{M^qNT=OIok_gh@r8e%4(5C>wq^78a90V#S#*{-p z@yZsBoU9b8F}mK+u*B;~xFJeWUA>F!Jwjxjs`ICVU6=|eH-mli6F@|k4*4q59(erH(_yC2;Ld%)-(+)$BN2|EbR9L{GnyR3C`YB z2j&SBP2AqD7b>cDlr>zgs%(;3k3RDY<}fuWR4t;;-enEpQwN@lBh~t*&-x8-KGfP= zDu4UF#kld1061!&@XS7cGr{$I>XQVJe80r0urZh^>Bbptg})eMnQn+m#<*&0oO;nu z9Hv=O1&@qc*q=)>(==g!w%$;q2bzMB{6Y*rsgTWBEmJoFhi-WAN1o+1pybG#v{ztX3z2lk~<+4T^5F zDW1*7tAVD^DNZ`2Yh0kaQ=bmFV(Ys#G>k%{Ij*c@Pz5fMl#bovB<6FxJa1-TA393} zDRk_qEjCh`XWpX<4@hZ$`+Q9n4aEH^PqeX>teC)a=1nlZftO8s$yszKTDMOF1F~ih z#0^5~O>svZNK~dys6S%kHd*@KXMtZx&8KJtsexS}i9)I6g7ljI|0+Qvri zL8>>EY+ce6v(ggA0Ky#I>(f4#?rvDIF4r2C{=(w&Ys%P3%x4@;6g1i&muAzOyeRuw zFPbh83i$`OkcCmlg0uup0)BzusR}P&`KAeI2&dlqHY%|ZnP-ru>>%3Dt%G?fThwQ; z@a{;zd2DC}mYPrJLLSoacO`i9tSbO2 zme=yx4G=Ml=Kb8k>Z!AS&XeLyAbpYeXp08rf5ExbfsY)^hShe^;Eo)XaZ;Y{I`Qm^ z;>~lBa6B;z>Hk%$qMf?M)&PO4-v|LzGfNt;^rP1^^|H#}atfmCo`{2_561lmn1ZAO z(b&kY36BS0)H2vT1@ODC@6D^sz)*vs5m>c!h~ z*>IWg9Quh5YZfKFHu1N!m5c)6m7vzA@ze}Zr`os${lrW1FN5;NG7!7VL?DG*Tjs06 zR-83hJVvmkUu%DP=GQO=VnoX-n(Nq}JyEuNy+Ri4T%99XQ?rVsQSGHUK?pe*Dq7-2gX7_D}~RQ{`kC7SDoYwsm3Q zkAXnUOm3`?*FNW;|A8hj|39$->ZQ2@2UA2IHtYTZSp~GlKjZ=N)}$yW_1cOc(tq0P z=Jjov#YXQi&2fR#Jz5*OI$6Tp4!@?y+&10kRl)VMO*JA}>>@W5tv}<83Tryzl;Y?b z*NjP?KrhvPpP-2FP&RkLY)<^QMwKqRYatytS-9pT>ORjk-W&I;lhre=ZoOjs&XQ`C zZbf?QxFu=@o9Xpxgy!iumTJ_w(H1_#&lg36MTFEZx>9l_cg zrot)?bHY)IywxgXNS$({uSpKgY;Fgpc@x^ebMLmGPA4Mggqt6d^Gv%oGKm*dA)dwd zsb|Hnrv_+Whe&v#z8ZE^buEt@sn0o@(1Y7NSiqb5xuNlJ70G9oMbdT7CEVqnBpO`9 z7p0`3xuiz#^tt&5e}jrBkM9@6>RYZ-DCtxBy!JM~ltE?a_FFaMq4;j#+F2|L>eDRU z<9iPFeK7-xYP4lXo!ERE6JU6J3jaYS%S05>hSa z{m6*T9TBYh#WRjS_jq`~;?+JGip`nXZjAJxwbmu>K;)M7FOck!<@!y$oO%rP-8uk($NQ;P9c7VB zyT?->n!V!p3a-3H|1zjv%AGRYhm}F(&|OBnrjx^hcb)(NPLb>_I*+|>5qg$$!I-8s zw$6!k3DU;YY5jVlwgi)b7mcy`?l_&25NaFO6#rk5SmIwZ-(G3(wi!%z3`_|cr2Emp z!;6nPaj&CSb>Gy@Sxq`Qah){4vP{J5ooTuLJVSSNjj`0hWhT?URhsV(jHJ%)&Hge{ z0STa-mE;XL;m2nKbGB-Pg}e^Kc4B=EAeWYD5d8E0MeTG?s)b2&?)W8{O~PP58tA?s z7($Sgsa)>MSLgjmUEv+Os1$t@OHAjpR8wO<*U1W>n~rs72IWa}VR+zXQT+8N zxa-o()5z3PxpN|;mwK*>EcD6L0##7@l8~$wFSVmep6Pfyc1pZj0W>}u$#+g4|8sQ# zp7EyDuD;y~+%$c1d=fBQ9D(B>H+ABd@+Yd&vz&?f7jE-Lau0)#8fS5Q(f+7k7tCpk zAr_$v*;qC2yT6`NEaF~hQiHVk&A0Empb*Ls`@JvH%<#?! zOsHVBSL>c}^Lc30eVcAU)e<>&N~f#@l3W>|v^q6<#MJNP9?~a`qn=Ttvm{PTG8eZl)B$36clcMsMyZ%gJ zo(KH>Lw^1n5ITK{3jWIzvv(rYlJU>$ND~u6ZS)**Hn#DIAc@k}pD4sR*mJ*i1O6bw z4T67rh5r4S%J-erCtdB60zZ$xBFKOJfz2Mj7=a3V_)}NL;zT7vHR9kwMRh18RW^AU z2N?;p^c|`M?4c8ylit)Xs!&iRPU-M(!tQo9y;+AVfBsE?Jt5%>He50)`UaKe6jpNtMVxP;fA%?U2J$jiu zIZsc&1lxYCdK0oR=Ew*;+?ObU#K0>(25vb}sE4W+AKqKHIk0`D_x&nsPSbedv-QKr z&B%-iJ_2NSHeOme65omH@=*y<_Y{can?W86lUiBFqcPPcBe6y|)t8S{c@U61O4i0p zp64xfKSpVrO-rh!X+egLE6u;}G`()Cf`B|-@!_4=ega(PM1m(W{Y!l#3nz|sSY|pQ^&XFDT;rE?CCe@L71w92!IvdJ> zb+E*mK{8Twz{esyx!%(3{`MjN*LEG@89hWt9(+dZ_IPTGc23jXiQWd@`sT<2bNbTo zsK+fQAe>#K!5)vs#=;{ouGukrlZGJvwV@Rez|h#VX-;7{Zf#j%q(BxeIH=f9*K`&^ zw?C-#=xwTd*@Aivz5LlNdxeC@crb{wCO>!^`qKX%bzhW4lXc-FY!WZQ6`(E z{Mk_tWkyE5I!~@0+{=;UB1?MtXYXxF#)-|3FjS+4F`P%+;)1Iw*n*RjFnlv)(P%x3 zi|ULltiN({mgwtIW5>>!6X8BSe;m&b((>rcohWk=H@=NQYkiTgBVp>lMp=_5$& zoKm|EikagrctO?bC=)hU62#gt?}yEIT!9va-_LN6f+%SWe*$y}n@d9I+CGmaG3rTZi8!n7)>)9WuIsIErR5>>%ObPKXhB^vC;k@xzk6cm2{OY^tcxeCoiusCW&o{8R$-YUNIQYCXunj)zHs63S z`r(T{#@7uS7UzJ5O>=?{k*Z#BM*lf|v}aXAWpVA|vXLQIxJFoq;r7SuZx?PeaawA( zh7`7x`|PN2zbxAiOQOX+RyxU9^`M(ro5&=WuZe2a=rNy9Id^!MqBmGmV1?cD+LMk| zHV!&SlY(g{z8uqKPxp^R0hUAKEZ0?KMDq~=tCv6Fp1J)7w-qJiMpC4&9=`Zr0QBrT zo&V-GC+nGa`Tr7QevzC;)U-Hj{F<)xq@E-WMO2g?E(j2Jx+a8 z?sYJ>WsGg>9@7rV8~VbA=kasHXSlcImP}b}Ltm&dINwilqRM(ga9M)JYYB4qt|rXF zAhGtM1BB*Ao8+6MdIYxM=r6lv9&T73ZGy8oCD04mJQy4%Ex?)jC8U@%wECIuN3YGB zBHz`_JWI@rBV-b~WWhT$@P1mne912Waz>Cmcpv&au75E*>!ygc-Ynt8b2CwW%({8H zn25fS4;K(?A#u)9}RV9P=WTo?mh7hWBn#kPmAJ`?EmVz)6 z29H4t{05m$E;7%us2}s&EK9udetWFFgcXJRN!e|IAtkv2@Q6PTDNj%G6t;noE2C&7 z6lS}wcZEME10mm&HDI;&jjgZdeJTnbR}mNXxnzWPoQm8P35M}Yl?sH{%ER4de2lRT z3toFSQIl;9=K@_>)TzrS7w|DVi|QE%o@chtlDO`&?6|*f5apw_AmzR=(wLJVC2eJJ z+TKG?XnJpq+nS^qA6}4DDUl5q0}{X+(_27Kz9xwGyi_pChOqQZ)lj$GaoM;^vVwvbnCi%(gYpR(A;kd_6F z*0G5|$4`Pcal4?l2=My?v*%Yn`Qi--ks2lXn@R0Ce9>1^${v+5e?moF^LF1_yVLi; ziZ)M^&ojD7>^m^)XUJ*n%rHLd)j`B?OZQMroCyMM)z0Hd1J>_tx|a#Dd1EAB_`5ij z8IAb+7TZoQ`DZIGazzYIes3E5ox{+IpFHnqPnX;{&t~m0>J%>1XdV&3W+yIm8VS22 z<}6dMP}hz#^$|`TnPgKgn4@>$iE6`+WR#Pl-qv(`5cRUKvrG z|A!ZjI3tX4to4zWOq(jVPtsZWzJ+AB@nujuot)(o)|IDY2Zvpy-X<;`&gs&)4c)1b@qJZ4F_APPop?HPN{Z6@1oszmu1=b z^1(fBR0ISBa&+Re47kX}`}jzAx>Lt#u|uo>iUN-V$7<-s{a>bUmX_b zlXN>c0fGf5NN{&|La-151lPgc3GNUexCICf0RjYfcMkyq1RH#CpFs!R`~G&n{bawr z_ql%{&r8!&)l)RxRj1C0ruvlWnaC*S5#}(Rt{D^l#RgmC%qy*B7G|1zCHW06lKN$H z%dA=RZvm0bX``{yA*xTZj$~K1GDZq&KcH3X2!7?crmvnDHNEpm2DvHvju3#%M1{i$FLwb zXBR>C;Xm7rJ4ucN;swIi1mnc(#zjFmb&_hD+D(a=b|$nv4ebjbm$8>~MIV+`vd2HB ztLUCiHz2Fu$LXXI=?U{YKhS>%AI;xYo#vWJmD*9tqn8M_3l6fZ`+j&W%p%zFi*DdzF#NgH{3qt~ z-yuLRkBS>R6x-s)$*j03nrC`>7*N9Fw#duaEqcYY#P;Gp`g6YFm-P*Habc@4{o;#U zi&58i1mIbN#sN&8^rq`U5JQ*0-m%c(6o-xqchNN!CP}{_l5FDxF}(?aj8tqWLOYrh#%GIMJ)ptoHetlt_{Uv7$(059`-%wjMGewp zTo8&+_(pzA5Q}hJ6%L6XKy_hq|E|r>!ow4V^# zhH2a%xuES!Q7*Vxxa}U1Bo)J7$M2|6W^nvcGW!~^LpJFVhM{qVQ|C{y)6MZf|NBW8 z!L&EfgYT5LrPg5;Fz_ltFISIGOk_t7U#bgN7D&a~!g`{QCG3hu%6!asxQ@SDKa=ns zAZDQMhE^RK$Tv5c34X7_GBPw`P0(W`*C)CHSc*H@H(X+-`V$j?#UA(?Yit*;*BLf* zx+Ue;31A|mjELXmAWf7(f7I~bH=@O*STp^{ZOCN#p^tfVOKQ~^oDQh;|`3Kp` z3hBkEeszS`{QNFchI$0PN_nKKjg{%Icm6*^7TH5bQ8)Iou4+za(#8sKak-b)`zhoH zTMVRP(YogQcE%k~zmpiH*-jo8*_31CMYb;!+f`Zcz34GdAMIOBaF?{d$w+b2TsDZ$ z=L_?<$x%o5B@@^Y(a35O{A@8x{K59RTk<(bQcU;L)0*@-*=ZkCD z?A5bQ$wDIoL(*BZELq8!xLbF8RI@H5vC?nVOr5BIm-Y>jZ2o6Dp~C*I zSd1yd!?%oAkJH?@#Ff8ETZMNd2u=U{IK>1d$4_!SeCNj;KGnSu&`pda}FBg?~SN(=Lu+tD}5QzT80tQ zsNvznGb7L=HmQ@fW@baZPnBStbn>%KB85k}MjEzo60sRfH1K`Q$^zQ@LJJd~D<{|5 z%&W+b+LEq87yi;i^cf|=1&!>4UejYCmnX_b#!Mr6E11+sf)DaoQq(y+N1nE0OTqO) zvZs?{tTCygGYw;+wc7i)kIK8|Xp5HFV*>oJvh-2Vz!@3H?ILAeGq1_rL1`~bl;I8E z8)Zc+)b9$oc#a9|nQ-vXBWa%rYyEVmtN`3ztU%7nxwe6_eg^Y;Y|O4vdcf2nbMn$26!a#>vtV9os_TI z2ZI6_0gcHwb6kxMR&B83c%i)XlEScO&&GloG2^qVv03Q_YwUn}&7J3J<240SBI@<~ zbHj<}aY``$3wnCApXriH!~P2xc)**YkRa6A3}^gGiuZhBxiR{in0=g6)*k(hM)&rj z8fUAi=MWxF(2@ajVv`z64vmt;ni{)!@1JY`#RvPR5C(gmt~UaoYa}3 zkYu0`CX{5ZpbqLYeZRHd?GPDz{eAlQatc!oN+oOr{8fJHRoj*zA)Fx2NU4|Tu{SL& zz)I$|_Qb*?A2T|55O^$X!~?()&#E8HU{}@EjU8HB zn7bIR{m$NrcF}>!ihk$V7Qm_a(hQ-oWQKuJ7HV zy|sGAeQUl8E!I7s)Si8($Ky!ZWX7FeQ6u_*AG?}NMU_6p;NN+0@J!2{}-3#5Zt61vHT zCJ>I2kd{BDwoLDM!I_lFIhKB5cz*rO)YTM5O%^tf+!GkaDt|QOE&mgI{!bA4e|*J& zVf@PzBx8*Jo?BKaDgb?2^%wed?IZ}) zhRN3I-z%>z62$im+_)L7Dw4Ohc2H1MT_&|NA6psrC z=8AEs%O`5`IYCa517W}FY_y%pJPU%aRv*#&OhzOtV5N%P8LEFa@`fOy-(2CNT^gZ3 zTQ+2*BZ5|*MuG_hX<~!x&%!$8pa%wfT7Lxo2z#r=O|k75ye0w(6HkJ+1d#S$aEp{d zq;TyA;b}+ezyssWv0D#~F%mpM+tLytr90~oRz92BvbC36ciPRLE;Jf_4rGWRQuh4R zdUNxMS&>R^6Cka0E{~WPrPecDYAM!8pgLL%-wCvrW>1)N915Q)@(IiH0N}g+6qTbo zatS;R%HQ@v)yJIDM~RT&x+mrLge_55{`oO9s6|O@2N%sHKlT+ACuW^j&U?oqHN%E7 zB(7d=3)%F$#Ea<;i2yYY-0$a#WDb39ktEK3tk#aT5*yVD7$RraG(&2U$pPvx>Z)%> zhZK=1?Ntp1W5M6~D$C+;LRK(oZ>V#Jf_xwNVS;j ziN%-CM_ed}pGky=%h1R)T3Qe#lnR>5pD9(e!eyQ}zc#3mBV!-pn|U6ae)!(LANLY8 z93>dfQ6Z5qeTh4&)+!>{zEwz7LG2*lAsS;z5N^2Zr>pfFd4FAli0ei{u=_i|vU3)Egg6=nd?r`+vUu7Tp;8{{ z0tG0IFvF_X{}lgv@0F(4=zs-Jx z>;KgjWvuu(4bZ7${r)#633ZI--|x|gaSP3}(!SIhkrOj1#Ah+H^a6gq3_leu?%g^I z64EnVRQ9m5@%@;KIik|0affDMaV?Js$Cb;RElq6Am&qqgK=GvPu}wL^Gw=@Qy|v zwy9Nn4z9flcjTQ=_VY>|A>I+<^qh}n<~TznizmPQJ;J2qw=YHvWIXQh0Dbi-q9w?R zkB6>s?J9W)z@+JoU#WM&kp1kwEK>I-vFZIzpD1x|@IClJa;BOSI@i=zW!;AQx%%UB z8H5KU`b7ZTj;3S^M*6aC>0tozK89~Pv8_!~VvDzatBq0dDKb2`Zo~!IGEl-9jJQvi z*?2ICGb*3PsWH2zPq+SXFmVcS)Re7)rx<=9JL%YXi#M|%dAov8N(8s*E#5p9NN_@_ zIM(dEFB;i?M%dKnk-HC~J}wW_>~eIx=aEHqo3OFVZ%hn((6lO$^)3_a@EJ1@e=e=w zoX*Njz9`2E{z3@o!afs0T>uoP@gfY0{j^V`E5^!K4){g{blnd#46mLU$S1He;BFW@ zC(#u;jp8D2nEybC4}r0D)nSzj?k0#}{XB=(OJiYhSCWZR@>H{>mOc$nv=-WHukc2s zFr?+fE2_tZ(u|s0^k!ixhQl7L2ed60tfhxHF_Ysuv!)tF8BMw0nq&Bc&_8NY{2)dP zn2n&PN42j1sD>Xv6FcPh@=k&fa@fqbQWZDc|AgL5_>M8#mks&Nd79g<*~>KcoESAK zpQBCg!HQg5m(P*xu|4<)-nxFC#j_#~6%Jm5**e0I_l6M?Ia^_vM2)sjga~h_U|MJU z>S{u%`@r#?P~8us)2?hw_t?nwSA0Y|@!B~juR%umtbqnK=Tcpg!KD}Ei$21AYj}vy zYh>_@h?2IpnE)}aY5^bS7CM%aY@e(hi9Z*yM7~4;%dUIazhexfN4U`g6jUj-;hvwH zlDBgk%RMQT8ErS5rpb%xB%7h?}=WQyP zbn^bugDE-fn_ryCr+{7U#?c>-F*2g$7mJP zC3o`Vj^yFthZ=DOHz&qrtBSvYgl|Ik!8j7en}PoQgoj{Ui-ajfMfY;l1hC2H7)rC|aH$w4L8a}wy83i$PWNOMUE@k&e4=UqCt zXVAjFj$n)0N!)&|j8)Q{ld`ghuo>vVkfK|*&5*|1PTqn`7T=_MH~W1$A~$r)=hOQY zYFuRfvjQFR-W5ZTD?%%K+s_xcac67{L3R_PKITW}3Bc8&oV#Blv<@L@mBRgyU8V2! zVpf$i>?^ln8x_8qO4Iq=4j7}3PUKX<{WTaqU_Drl`u-i!oq_EQsgS$vLTYE^PaQQb z+t%c?--Sr7ZzJe!O~QWx2rc1TwvShzd+V931 z7GHWbPWO6rZFM55(h`K?z48O^Or`Z~qYG)t#9&r9cD$l)fO4797?zPlrZ#pX!)HF^ zZ)uC7Mmjy3HIz-NOTL~Mo(_4RdeA%hal35Fm+eSk_9QqIloi%Ki)Pv~PL;yd1VK8Z zx3a_X?rThs$r7)iH3W#DJLsAZ=Yu#$gItMW+P%aCeJ15Ej*{y$Yo{N5?ta=GYLJY6 zimRshkx=gZ!RCe96=Oh05w*@>Sw=cgVshwp0i(>Y{`m94NTuNL9=j=QAkXa{4$Y6+ zYfJ4H787@M!lref8n)C(N$&xr#um5Ey+V`M90jF2(yPYpPC;Gh$=G z;;O8CN;5*nZNqyaRG{9MSX)vwPjgSWKsEdG$DXJK-S*79o#O?K=0*=|CKbKYOq{=g zyuH)-Uixi&30Bnv1j25jf`s>J@H|;d0PqHNwr7Qb;g9M87iV~J^42cK6V*{ zr40t_M78z$mAmGyqKmxS8ZTn}yAREAA1bK7``rp z=z*!JB0@Kon6n4ktFs@goY>3wl%3VvYq18Ye)91s0rk}hg!lb>gg?|0g5~4&+?0ku z@{iYys@;8>ErIdeu7d5kcAs%&U+ut;X6lv}bxG&xXg_d*9IIX``u#ZVo#sR)ljNyH38^3#8+}4S}h8UUqe{^{_ z!LeeBF;5io&_UnJN2-(UHeW%X_{Q`DN}i;j@jr>#-0|q@Brxu^9wZP&#Z5N@iDb40 zCqEkBGR{=LS%&Dc;>(DdPhy4erw)-4Prd%u%879uGSh?z;CG{nY;v%GHm6XE-`}gT z(zWWCUEBR>Mp!x}wz!{&E3J@)0DHo7L<+zgEg%*ZhYm`=?=Z^BCJyHn+B5)k*-?JZ`S zH7Z-=_~d0z%KQ#Wbc=nYnxz^9Q|W+{;bzpa*(R0naPx#+AWz-{WE87YV~Smw%#)Vb zsge)x?JdUBGk~uZ^=hGU9l|a@FU7y?V|ieJap!PQQ3){_7dWAInk$UX7gt`NH~!M;a@@N|9~Me>aO0l;)*$ZZDJwwCTMom551D zYKK-SlS&>6zYCPyN6uz``NxIY{zw6{%rZ8C1-VE*S-nwDVy-{uLZdU_H=5#m-?Ht* z)(ZEbJikBIQX&Od@#OR+3W^pwapvD_VSegp7GPe0s7g-SN>Xi$G~(ll=B8>@jD0&p z{p!0uRF8IF8)RnfmG`hH)DYfeu(}EfW!_~dk4Gv(9b>QuJ-`hwp%cZ5^-Fi5dDyIa zq+I5!RvFZorK72!tNCHRx!I>haDzgk%O-HLQ9=M@3$S>f5xGVu1^**H`R0n3Y`@^f zGE#~wZI8Rc$fOLRG3RPaQ_w*$=@a#Uzng?wg<)>SHGE{}mdn?OOYNrukGsbeG(>!k zhKtps(YuKJK!MK|Nn%ZWPSRwTon1KZT9!yj)`m9!x5uq^)!XxRY~1=Z=(rKx8wXg@>o!o z0_^Tp5aNCK6+#v0MZ($JU3ppFkX z*`xcbGCD1#Tyi*KMZ1y)3G-cxjA#x6NsXS3uUXd>RnMN-5#L4)ozQyfAI76sP9)I3 zpn+bx%URl#_~rNIFLua1=0c1O4&j2UI(X}Hf!>a_k6%DPhk2gSvkVF;kM)ri;7u`o zC`IoG{+Gsd;^FmyYlk*EQ6?d)aZf!4dCQa3J&Y{|$m|TVJXG2cnA)N6t7j(4Etn3TfeK-JP2;7r*(sLC{XqQcGq#Ts0xCu7OZZ0*G*(epsXTEwx%{Sos5l2~c zypt2=uLj#`&f(sIbJcj1wAs2`ku>VNx=77y-D=Q|WR8FcJ3V*1gbi}DJT3nQDi5j| z_dY~2?sNCXzUbIkIn5?&5>Am&3#&GE;kwlnW|)gFB?bFjI8v41p)jl+TB`|p@i_A$p= z(L0*st72O*+>BC#(&(&p6~pC^IM*S9Rgj4EY0{sA_+dXrUoEP~Arqy2^DGxS`2b!J z&L~|Qjz5b!58!|iuO?KKAhwiyIu_FXv7OYk7B+LQRI}xVqg)9E90oXX zlkThXazPKw*8L+m-yXdQyKX~GS>enfR0#*Q$Ma%|O6lvG>MP7M6HohKY)YkW1ezY| z0$AtjLvH8mDc{P#46gWEymXdntsjFiSU@l9a`c25^YQp*CRZbNmx}5_^%XbP@{~o< zVa@fM*4Zi>*IC2iG5lMq*F`TXxxiU#u=gcU%+-I;yVE5)@JyFVT zRwSY#`hN~%PE6*SItlt)#%e|f*>Pfhi}I?l~8DiFqLah>E>I3R4d7wdHySaH1%(om z9BbPwrbNfokXv*V4z~bQ6E?ZxLm5(Jv!?78M@@^~cD9P4gMKQ}azhYe2+c2hOw3FyplmbRo!TF23_DDNuF9IvU=7ge7|g`jzA z4*pheY0d%5&n)=gUM<(iIA~2*VMIRBC|VSbZGy?yd{XaqhVKTn{xr5J{1EhK)FxGv zsC{ULGAHoVv#Q5`!dh;gdEiI50irQVj~Qp4>rvgDaQVamPWSmElRr8>=4ReFvDwkC z*SktuKT?}H3p~~NKiCB$6;E?=e(2xRO;_m>3uHFRI~5^rV)so(I)B4XVc6+J;n>fY zwo+Yb=$hCIZfJktL+A%?1Y_7!)2d$|&K;_u;7R0r$mo%CB&xa%8fYb7O+gRJvqIg3r(Vq-e0*U$-avusBz zq?BhGbvafyFJEM}K-a@fp8b&$Mvy8X5}|5@hcpCEX4!f(o@Cu0j$GJ@Q(n_sF4I5) zYU8|Ghhf{uz=81BH{FlX3)Wk>E&rLe=!K%ZBDqO1UvY_oNEBqDYMcM8c$ig0UC*)(pZfV~g zfD`XofK$!Vp^5NZfSSPdv@f4*(TIb^^O>lNSA00iw6@!~Uy46J8{X*sV7HFT-RJ^3 z2zpWXM?#i6%IT!~#FOmQyg?;bLA2z#3-ljV4JaRIQFE&>HM(svi! z`}rz3ERO{)*%R_0OEuggL5e@P?yUbMvv@GcHyIt}72RUdkI<|V*y;LaP?YyZbP)Lz zw2MZyd7i0hrm@3N`Q(_BYv&XD^2CcliGqU*R1u>(v$)g`0W1g_=00g8OS);_ujHmnEe>hHz@``87MLVUs%rUU3-{YL3nvIrh8oL3C38C= zlWFDh=b0pH3d{()!eYf9*bT-dsQ*P zX|&WQ(96cY+)Ed+{e`Vu#DYPiAs{k3J<5I3fymIKVb+_SnP~Bwc*g0a0`^a-!5T=Q9;<|jsl>IK9vO@bFd+LR}>nN(s3kIjg)5#U&4mE*{q2QytV->Nps33gU zX%B3MrBfQ}^1{$ZQzl!pajx-+^_=aCUS{T>gv_JRn7ts%06K);6Werv zBCKHuLS0^r&@X9gQRV(%cssH4lT0JaDlKgm=Z)*F4PR1kYN(-~;z0HUMlVG1)8+ky zyUTNZ$f^O@a8=H_g%tktYaD3|gSMs9B-r`yKDbK}KYnTKLG>AzZ-sSzud*w#t#A_) z@P6BpYBWx%5E{ldv?JeDlKATDTR9wyo?X zf;O(-`%d_}L1;sv}tndZ;RWMfq+srz{mblKG@oAU?YAbCCR63gJx#^Qs zEM9ehqw?tHCAc@S#c7BKJS*+-T`oL{5-8ocj5B58K^hTkok%&B=k_s@STR8V*{0bP z&=2FVevbh7k^l3Q3sfrpJ5}62zHcd%X%U=zKU_wpek~31U1{A%AJN=Hf1fY8DIM33Ag!) z^LJfq5_rAgkIzBDvQIcORh0qs#UmC@PN;56{o1dhHFR0{LqI67DmhY&m??xuxjYmv zsvYeyrGCKo`|__ajY!a7v8Bg^qpucHCWqy#AB8*)I<}&8Ke8REZIQFfCzuBIgV|a* z0A#@{f(eke&!b(+P?AW+2l)`6vZZH4Nb*JE@w_S30>MJ63h<5JXv%aGavXY6O>RX; z8ugZLGQ?OY8eb1*-D_JwNO95`*aMi+tZ|i{#{{AjpG<${T{I+8iGanv-aWc5XOWBf9_b(? zgohzqH-UPf_a@l9y|q3^*)9E-8{4TP8f|J)D|J^zWBp_2gQt}lDqnM=_;9EJKs_+U z`gCCyGW8p22;{Zi!aRa~WVj^pViPuhT}9-vzV>F%vsd(SlDGeH#&?XFia+1|F&f}) z_$u`bVIb)-_`?z|)!^9eUJD&&8t`R59Nefo^#Rg$J!Um1+{3DddWb|gSS{vAN99Z7 ztbyL!KKwU0GlQQ@Q+~PLI=Z8a*8H$Au|@LIC56up^8gt^QooWd!*7OYV7^m1BKwK+ zLhj!IgUG&Hb=8ZPH7PwCCBTl&NR1n%Fxy0Kny{rV)FNg*^vw6AZK}&Svd7CjJw~O; z2M-wJC z_d^C4D|pcXAflUD1XOHp5Zdq{_Eii;p?2w1#xK(=&U{MCz3%|(Z0!+~rUUw|m5|_3 zhG0P12QlXbZg{9(qijN3No4g|32tYfb-Q}lN7+3i4bV>=5@TPAmo#1Lz0FLkL-@Wf ze_%z#3l9*t(pV(iOc}W|s&pG4rBbC)N6#Roy0o=fD|rzh3FfrcF*b-;4V(_FVngFV>-ahEiGWWiN74~IXmuou;DFV|M;ICTmQr3Yw(lcUmmaj-D6-Ohb#WeW1_!2&TfvtdwlrkjIz>? zph92?Q~o|<=YOuD^kx~;S)m-@G9zH4Hc)M~U!JZgCO{Y)EDjoozC-$_DSs`O+JD5yU(5Ah@u7yWe+J|y(EdNXQ#_Fs4*ch90Ufu0 zkAtLt#DTvF5S3(iPalz>Mb`yDe7NS{+x-<0e~tU^CjYmA`GEDnd;K5A7yUh6kY)cP zUIb5kfY~gLZh!w9EQgLjmx2@16ML1ELZrWq{1SxzO} zzb1yalbdp_JHz%a+_0fh+Rk!iO+UcOtNt8>y1gY@BhY9(QwvZgPCbdKIzPOFJFbbs zu@2jF_aLXIC*LkY6g5!jZq0d&QWmu_Ttygi%i<;jo_ z+oIe|UF*PcO!yu%ACP`P8JNDDbisQ|l@*0MJ4D(~ko5{V2tr$po*-!1A_T zlj3FG7bJ}ZNj7rz6bIRpdJ&>&CmHg7K0hsMI(E(D4ov0}?j@~rTNLt>&(8LpF=Ji? zTTayxX>-aisbxiaCE`3%r%FD)UJ_m5AMqQ7_k8|1h2sO(>X`rDtkifEETxsDUhK(& zCyMsD|Ax5)q`k-<`S`t)lQb^aCZEzSL#evOK=5bveq4v1!rNN;?Ic$P(a~zPA>b~3 zHjs#XNa5KN$8{AbDrm?X=u&QUP>-!#1R*>A;*1+)%G36$TQd^ciU$E0^>+}S6+yq& zSnClU&{b*Oxuyxp$`i-NJtt8|nr&s@pUO@%>Ht3RUmGxbc*@2c9L9e z)l^ZWrXqL)kdH-klCGm1Ay{9b%(TiH;y~5-Ixk3%+Q1sPdR`Jtag|T~G%3a%7a&+| zcxdr%HsZngw=!Cs3R>Jrhj4^z$WI12 z#8rj?7wMJnh~E{@(gBz)02lr;|9KDtcs~f80Iafk!bC-}C7*0CFKObV^46xQm9gkz z$x6B{;6-9r#47k5BG`mt;)}b{vXR{llc4X%qnSL(U-LC=s zbllUV$M|;>#Px{oA7&LVIk%FvZqp_OR(z6PZq)91(?Pe?F_7+pvd9*swwv82Fu($K zqdhySAS_hRH17$`B`le}XTMHa*MJQ>4WbXXe4}Gd|d@mT%u+r4~My&n)vVxZ}EdMvwn19D4 z^Z$DGZ&+qD4||&7b-wgHh~mD6I0nbDivFiQn%f3RUHP zC)S-rLF%9l%}HpAbz%N;ynf8{Ff3gK3PJ=8wGZt@2U~(8Gw!Z_Eo8I=QP!t8R77%| zw|o&b_sjRYd@OpoknuEPLJxZ?grN*%35T4%ve;A=TTtn&)%PB=UHkQXNIyS z+>+YjHFk{u24Z!QlcDjidw#y-?lbILgMo;+*RdCtVr_%1_ko`~koq;}|L8*-?yA!J zda2AQ$J*|58XmCCh4{n5pgi|B%pnP$czm@--aQz}xU4Fk94F9i?rW?M^SYBYEz8cX4sD6`Z`e(D2o7(sJGbilSo zGTPN*IRjpK3MB?IR;@OQSqw9tuRBB}y?eWjOKCT(AY0SoTx}HzQLKwo5i8^!oM;r^ z+CjY@I|HZCG~$ImDBHkM1|dE1oGqja%*}0oIL&#NC6}!g6KIu1K=6eSKHmbo-y%I5 zjqA9;)sAMiwDtGHdl#!r`tEwAZ#32)N5WPw`bp|}n5f`J50&&r10id=S!l zOPP~8g(6KGGzp{=z5$ZFsRI!70?T`;avwrXYGGg7l6CT}Z%<8k%oxYKH-Igl`sHJr6uZw`%I)8sZcsAK53R!dQEh|`qLWH| z>_lVcN=DqwF}n})_X>!up*zOwd}t5RQC3=asRXGo*twmr^ZYgMGaJXYrJT?llu7=H zz+ixj2^BJ3eW_J9AD~t>Zeb&EzPPw(C{JOKX*tQ)x7w@z!+mKZISyJMpa=|||7{Ah z&UE^2V$WS2P-}FkPH4s%$)x$>MU!&>1~q>c2oZl;oJ?%I_`?Q80_W=C{%%1H=F)cp zXNQ_Z6->@{8su)fiVclpUSzPR@ScZH*=G+*gC4+}l3vE*LlnfPx!y#Ct2~{^BEK|P z?5M1mEq+9jv#Bvt+0%pvlXyypbxSrZbaL+q4wb)xX3FXpNeAL#kW&E^I?`&5U>rRk z`(K8Lph?J2G^}ppN)@tK3e&j-mK&a>hmhyhUEkGgD&I6L8*wc}w~pQ=03z%M`s>dg zG|K>BPoGy-#%D)?N1?+*!LJ8*K?U3a#b#-1o4Pn2H@+j~)v2S>5g=ddrh8Ufv8T}L zgPRserQD!!GT3+>GFt9__5y`$MOFrV4#l2zE9Jd1fIw3+76zo>Y|@X8lQ~o*m+;s( zEI1aolmE<}aX)`=DXt2V+a*{Km{1jguBJAdVedmXU5MqmLmwE~53+DG%H^EO zjU~HQFU{rZ7(>4ZcE%i>zibc=`dah09RdFq-0$W9+(t0thx6^bIU4CscU7{3b1VA{ z!*TztxqoBXGXD8Gs&|-e>Ue0YDkzXVG5&$o4ae)+tAuv;gaWFPVNRTDY5lB8jfwxF z?6z$~cUp~NJdp>baT@@i{L!$^UF!ihpoIsKMsHCUbi@-FAHl9Z$K|A@Qo3T&Ytd{z zCcU)t5$)Mghv|d6xGrhY({%fne20#1*oBduUvQM;Ri^dKHXh^9(5QLyv~Pqay)C&l zXpfvYoqv;(5AW*Y(kERWG#MAQ&B;pJME^44tc>&ycc^P9YeyC!$-PR zL02MFC|j4*qKN0gTVQ1U*FjTOlD|l@Rxe#;=@qhTZ`5z6KS@}>S;LU*BhG+jT&KFk z1e3TtNV=37mZUYuI{X+aH(bdKm}M*CLuw(TwnjmjTp#~)e2L)TC~9tqVX1=3Qpi%E zy;0{OLh1#1mD9HEQ9INaMBBNT^u0o;F7sl&7ybhJ~5TOeLO z*J34NM;Bc>-KQ6|bk%WF|0{8IDpdGH6ED1UCNi~f9XwDbU#`M9=4_iO6@qoI7kUVij$u&04 z6;E%@GtP2diRfTLeSf`s6OpzED*2O!)T*xHW}M%D7H0uvj**Zp{p?7u%Er!KVcpzr z$DD`#RbtS0lTJ61Mbd=d5UC0@|RvptS}xixAz2eZC2Vit9rO<^N}^R z>DhVgB|)=UH8Ip{F4(qrTJy=Psty5>ce;7PG0&_&#($v0e%fc%VUu;t`zpyHO%W&E zFfkQ>Rndb5i4BxeeXWxA$M|yDQ+qX<3)%Tr0mY0zFRY80PVb^lW^AnYFwl-oQCOQ}5F3&&ZnVK+sHNC^yV9tzKW$j(gLUE4Yy(dDXJgGO8d~ zs)qx|gHUO^jx$o9u=8<^-$k=)<3@l%Y&TI7 z(jL%UukrUYT9WgHZd8>l6O95XJlf=vqLQ{KGXf6mu`Wy8#_f4_@l6ZSC&ybYD`7wn zol3_>($Hrt9{%2wu^LuprtTI*`8~Ty&{$7>ca1O9SYcLYu4$~OwzU?^WU^NrXB_F3 z-b4hbt+#I&6S@1HlF9A{1Lov$pEkZ_%6kxUh$P0f`(x>Y?mh2=Tnn6ZKvlue|Lan~ zy&ZWLHllYV)irbQvn;Jm+F>zuPZ{v<36Mu?0AoFPZXBH`LW>&^)QA0KDt0YqH4Gie zX>nnTZ;D4_WRSkH?j<$dMi)E{uM=Di;YhGn7`W7BJ@Jj62F(UHpAFJL zQla^=w2zs)@Ly8c3(R5izd4dJYzXN1#SJ5E2b?f$zG7gwiqdtWK+#*^Sf^tGiP0@m z+<8=V0+}3w2hO>U$sUBn37XA4L3_)a|p&n zl4#AhXbwIWq~*jafgE9}FF1QyibpcotrWy9)>%cOC9>fYAaRl1ZXm}KmK(rW7q#(V zun-}zL;}C6^DXO2A*{DXSIAPwF#RFy1~3`L#f-q$BRD#pHXT;k2X&yQ{dY`}&{>q5 zQ3b59pfi)AEYQQyV@?njf(FXibh0pvN2Bj!?8L-Vox!5F*Jd128B4z-v*M~S<0BC> zvCv~(e!0rEyC(w=4!OE+zRj9doKIRIniR&|!NlBt5#|QAL-;>EYuRu@fui1xuN-FR zxCo>S6^h0?eZ$M)dVOkT^iYsDAUdSF1&F@V44l32asD}?lJGasyVlz18S#Av+zWBO zRF2-nH4*I46m&e`3cwfKCw-Z`F$K|7b|Guf7rcu9j+rOi1<2A z>43^o&8)IvNuECE8pHV4Yo|3N>5tbnIUW;4>KIK=eOZs)+4u7MwGM=ZcH$N-Mk&zW7?nl>R9IS-R7;fa8sdE zzuy=?$b7dcQ1wMXsX7+yyk^)%UjQmn+}VZvw|m{3KKTkT?tv2(UHHA@%<*q>#jh3@ zWVvOTsP4aHwzslCO9W_|tsV)HbwwOjb6aV#pCPKD?XKC5q zVG2#qz~{%7wQY%gr2N>iti^<=t(u~@oke71GNijJZYC4=>`#BTwj!$Q^O#drn&wJd zGYe;qGa(iv15M2YPgT00vAm)rei@p4)f?S|M^(>!WQZrCZgY3GT4zRkj$^dVOPheE zageyaH?%3HS&4pUn;^+oc)v&O(4h>$xp{_A31YN`=mUiiiu6J|Tjvv8#!t$gST1r) z8KM|})O(-Cg76Wf(C(rQB?eeVJZF)Ag`t&>E$6c7hln+%dr|e%jy?`@KQrAbzn)kL z8n|FJ=XV%5x{7>felu?udnev3vX1~YX}H2!KXWvxd3TgUs6GUAp8pA44-|7FYb@K~ z*3B6PO%d@e5d2ZJ@|MM)(?ff{K8$?YU&2(J*Ki>>`O(tP)COM_pwFE-;zoI8$XE4F z45N$oQ5sIS4XdF?iv!de672pSK;uC-5Wpqo+^Bc)C23bp7r$uvl+MVKqoycJzY-@A z0t&U?MJm=KdI+i>UI4saREX-yyZ*Id){`s$c%_n~N%Dj_>#)E&XHZ3lN`D&Ls>56- z0jx$1;k$7(LD^qHgm1jEx|;I_Ihu>n_hlNY4Z7Tl4RI7~e1k|Dw^P-kQYEN8p%gs= zH(c^~J|@LT5ho5VbTSy{VyZ|BpKW)#0N))7H|Ng}YXjZj`4k32Wh%u0cFV-xTg-Un zT=1fgvXfBm`2IQV!zzy_-N_RJ72RO@)UM@rJ})N?xjQ!Qf`hmu2%#cB#g^0^hD zVJj8>8XnkP+s!o3m_=oxst?uiN!eNB3mM-Tl^6p#x&;1|K{4$u&Hx`3DN9M=QhN^I+?8#T-Veo2TJ&y5nj5Pn8U5J#nET!f>AWkD&gbR5dsAx< zjm4=czx*yH)!y!&02Q^(Sp?s`JXsR)DYX1o8h*-oDIyR^ELVX8a2tR020GEHgeZrdRFuH)Tt@Z zV~85ml{Gm({%%3fXaKDTGBl{(-oYWit=-G`x{gd-c|>F{W+B+}-f%*88#dqKT`E#H12L~n{jb=cKQJPAX;Kr z_j8#$)Am!* zP_<|pklNsL2c6C*NNW>CRh&?errhph{UtB*{_%rH>vsJ|5SF~K~1dx z8V>@}1u4=6q$$1kq9}xph673$>AeY30s)Z{dJzN^5Rl$m2wez-CLkz50tN}~Nbd#$ z_}epc@65S#&z(8`D}3P#vRk>%*=V48^i!jZ*vJPa)ix< z>C=N0YR63eeai^t>8^0R$<6zLdnlXfnsW)P*?4EAs6g4?K64eVp@t3*Zs?&IvfS!& z(yx&HiHBub5z8trvli!$(ee-!^=y+mg=n?=gMUTSa%H0Fo~6#o;riUJwc(TXgT0PU zTh>!3y9#9#gS_6usmxG6qDHWB{62To>&)X!erVDV#_kgmtHzgk7<%fL%3EG?t6*G< zEFjvXpE9)4`6PydbXBF>C_gZUVGr%7&aZUr8TZ1%mnNCr{aRP^Yx4#J7#GA0Xp;ux za;(VHySgMkgDA+`>-EoOZ1MVifRR?}e~SSACqwRU_x~wh#IxS%OPxajT92=Ql@Sck zeoLPEv+J%fgpfV2sGJfy1*xkpf9VE=1?3a%3B(~B)t7Vb${~tG30NzCN91NuHB25o zI1qGcCArJoCh)Ee$#N9emr4*KFUwLW#Ph%{zkf$`b8lG|yLAXiYkRqF!pRJ4YCApS zxEK_Y=q(RZW3gPYMlgyeuJDFjt-(WN`@TPo4Y+?+A-%(9zEQ$Zc7G);+IIp!M9S;j zlSL3Gh6Zacv%FP1s zS*43D#8l35&@r_|!i7vk%N&#XX;of59AE}rvx;x+WP5))q|inB_pxT?oCyPF9Gz+AIGXj5v*Z1mBFnR{@u67R-Vpt{64O z2s5%9N)(lc-yKd~B|akb1>h^rxq(my5mR0xfOO?K8<1`Ow5Dc9>GVJ&((f*hGptYY z+~GrT;!=5hjhbTdy@a9b#M zZ}CA_!|b{I#XDgPk2&#ij2aTV4itcV?+m|*kWhcP$xI9S!)4oUZh5&Zm3aSLscrUL z2=_=v?y;q323)8yjp;z|<2oCEBiXY^RZZbd!`onYMCB}VtXOm&sJh_{QWK)~6)hH6 z&UT8A!lHIAYOtfi49{Q5{*u zL^jO~Z4(l3_f}CVKl?@#Y3!G99x_`ezSEkRE0-AH;(pM1-_=PbhoMm=4tL%YTqGpKC=OgkacNj?@MW&oCDg7AVK;u>lX8+XSnwYs}zwbqHc}E%kfa zGS^M;z2QOUb3Q_D$essYArmhyf|=e}*Lw>94K8J-dLFw?NP#JMQ{pIq=INOau=CqZ zK3A>07k0JTtrk%!AZ7QnY#8iO&gJEiXosVqRB7>-ivjdL&oyj_u=87A)r|IppUehw z>z{4xY6X`?8-4j+)OCMA9T-aC$-+itu&=S^ri#<(0LxuwRAX~`M#rj86 zS`FCxA;nr)-4O4IQr+Z7%ksp_>y{||ZxCtgL@rm8LD^6hWl3Prom_sBzR6LQWm4_{ z>j1jLG-DD^m+7A5z1rBfB@sh;3MF_Ry76VU-PZX{xLCv&!6vsT-axTQ9yRjC$@=L? z4PRmTuTbuNkzmoGGv~Gd8k4JuAs#R>X$1SUXvLG5Np__njn=We%^uS4BToB1s3xm< z@p(G)PZzn(aOnUhawUpb5!NCiD*AKF^o#6|FhGHERnsk>zTcKTVScayr(I)##Ttc_ z{+xOnb!EZp37dW&OFCT1TegvKY7{1nqEGG+9z3ju_0!5zEl&$QDZp<`7zCFKz96MR zUb*)z{qu4CTMZ5Z4n{CfBV^hTG%Gw#W_{fhSwqc=X1o^f+!A$>5{Sb#(+we6|YxDSHKJ;l)?Vm$H9V;@O&(p7$6^zE#=qidhO zVl-VB3HMtzbuVuPNBjnXF~@9@!p+k+|HyK=v1Gic9&wL9_S9iDo@^PE{nh~7tc3}Okg;MiGk%jMim*-IR*e~r|SJUYDt3DT00%4wtTG8Vy-pC2^k}!!z_)RAi2%S2?VD?QnAe_%>Krk&}~F@xf_SIg6T+& zjaH8Z(Nu-^c8w#Xo?S=my<-y76IM-z*2Noy@IX7NU}_p}ca&CVkCEa)w)i?)2QvNj zwb4{Ax6SD7XV<~(et&cY?%xVmn0(X;%y3O0w-8M@hlg$re;!TZh)~X&CJvo|S4K#^ z%1334ymPktQ-1xzGj#E#npq_wXHhY}g{JnJk~5X-tZ7N>f}^8eYe;H?$U^j>A0Pm! zc)qP~;M!$Tx}hSDE(!?aZefghom0E&`YMB2$&^nATN0!+!ZLhrbn(82f6g7DP)L7H zBRft3H#O`D;mupaS^4meI_kaDVUkb?iIk~+%BbiV0HcWzhd$c38z>~dw_F%^Vjdbe zb6L%TD^*AoF!Au@qTE|ar+JsZ*ms*Vt2ee%2=g)&W?PQ*DCDS-<9St$Clcu(susK! zMPHm_AUlxXpp8s7uPQ74T`5wv^l|?);q8E8LM)DFOI+Bd6G;pzEdMU1u*BDvy~RiF z^14{RahC+a7*10Eu=jJVyqAQ5xFrU=HsN@%(t?EB3ft|x<|hlgZZ;X+Qs$QE*5OA4 zHf5O}JiE}|<1pm9_tk}??F6<7QPg6~VjR?^y0$PzAR`2ZSp6*EktHp%@PS?myRd6c z={uG_Tf|mQ&^$?*Y8`2@GGW-BZsoSqe`9`2?_NuS(z_3%5}dBi5GsE5M`Pr5{hC)? zrwlUy90pwM#no*A16`EZP)+3a(&VoW;+Nhf+G*%4Z0oyfSP6RkMYOP_y6Cwk3wBpEeliB4d63Ht6+p)vShlT-OWyMQWKzHeoE9Ua34la8N;3N${ju zf`^TWy?;GRjo+AB)qMJ@ug0_P2IkOcYmxb%y$)On)t=dv4;y}Vz@K*-?P)ZK zhy;NgGm{?6YXe-7Y_x`Ts23a0lF{MYvAK4{x@y4Cs!?$y^=;tT>|s5BzHir8-t7~c zw|bcpNUn_}a#k?DQa0*~;tC)zs`yzaGm{+O1Z*$lb_BRvc$q?**Aj8eLyP?D9asCX z{g+fBq}*|75!$5uWmGI-gRnjGdJgvxyG9ITX_)Map?! zR#A#5+YdtXfoO0<;og(5)MkCbJ^9oE-Ge-Ja}%*^#KRjAIp^--s+Tkj)l75_9}}j% zf6Q$RNNE1>bI~k?ssaOLm+c55E(2Z;=*Mk6wAm=_Y3I~2#8d%RwZ54fxwzI;ExVF= zF*P(AcD_`z$;xqA?iW%u{Kfja{-J@WgT&TgZi>=MhI=hD2vU->Aj8F?Ofj7SRDNxj zRGa%R?oLC)O6wEl$6$1eZVyLX-&l74dgBskFJx)(obgJf^t&OUtvanA4glBAhi2o^ z2Eu9StEar&kD)-vjTc4ikUl-o@z1_ZJ9tsTIz_!*Xq$bNtwqnagxgaml=EDY%j&wO zgltOt_FbM3Sf8DmU)7%)%zJflrQhX3jgj60JuTmAgk3F#;*cq59fx^S~BUwkNbg{mBvO z!e=u5L1XZStcjw;fOp?VEXl*WH&Jb-)2+^X*J|mqvL?TI=h1=3iDDy6GB#|(j3LHX z=Yld1J;mF4M1>4OZn0-^>)_k%Q^1do-_xiJ#Y+ZWXjyf8Z{T+}e97KChR9{;MS>Pq zR`x(EC(PfitU71C8Eu@`JSrjbaL4>Hh6JhV$)`#z<_VyO-+qHOF|T`MW`y>RLLYR* zY`XcjXQ<0fEV}3j3%&}O&$z2RBRlACiY-Ky?dNZr`L;*A~o$!Gw|o_8l@@owJE zi~b4=oXcotirz!(fYfdrvg0n$6f;G9l8rEuLAC`!>vXk6phan?6DO>|f|^+*TUebO1as(Z z-WNt?w`(4Zz>col7TVeqHDSZ;Zofg+fH3qP%g-Z_sZ)%LwP6)X8AW@D1(q`NUv!l@ zdyB@kD#SFKH+$c4`QQBGfA^CAKd%45iT-a!N2I~}I_;V!;6#gvX_dvO2&Lf1x)><= z@+6(RCD~cb!o#=uvZgVRHOvOa?s#vKBl|SdJ&Rv#fSjC}~uT={b# zw~DB0Esrr#Oxl3#q4pJY!-w8YGli%I#c<>})MGi7pxAlx90OE*Df2{5+qlP_g^-!2 z``p`5{{U3c9^wE1 diff --git a/doc/pics/subdiv.png b/doc/pics/subdiv.png deleted file mode 100644 index 21026e5eeb5b1fe03a07f6639b00de348994eab5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2812 zcmVJ9Ma)myg97?1nDh|AE<%U5?i{!N~Bcg15ijkOv*>O35IT7&!Gi4E0v) zt?0K7UC2m#cx0Hg*~c@O)yqZ|V}jC#3u8?Y&NSLTEZ?5&XTcCCa?XLB{4>~PvG#t1W^nHLNm2yi0?gif3yvGj zh|yx?eHLoJR?V>fj2$UrQZ~z(7+a%Y+VPqRoX_Z$YsgbSrOf=iCVIVU+4p{OBR*my z4VgmAqJOZin>P2204axhvvN`w^>WbCnMu{I*WQfKl08Y8IZ|(h*Y6vHows)r9GOwa z!3JY!-(IORCX#O(2%)_%&Iy9VG-SX#ZE5&5*NDbgLxDzo++huQa)z=2*x8q@{0J6U z$HqeS>;iK={tG43R)Q^2Dpp(H!VaO?+-|18<#F=p{uHAM2rZQR?^~*~mhmCb(@1~` z0c95;V;!f*1KSg8-&h>U6$^6DlS;5DS)$Opv~>= Fd(@4zrGB)DxU!gA9)e=mGFyU&C(MA zM6xn2N*KMPXI{0U)vfyQSe%;#g3#~xIZuXnJGDoq)2}ybdpD^efp6RRwHl;G0QDm4 z8@&^Hpk+8(H(uvwaAK&=rF~~(=Kdl0XEct;*=Jz&+n=ICtCEd(;q&+Z&2Aps+SdXL z8w5yFd-T8G?QGDTc&;zBF+F=0+mEp z-wu=^I4xFMI7JwgPKCosGAl71*Ql6q?53SkLK;S+ZjeU)m8^8%*o+htlcKQSar|f!0+q z(OM0OEZFy`?O0F7E3~g8LB7XOmN8qU)4#rj39-%u^IFRr)(kOow84+*)>G(mk6uxg zB6Q85imlhPd8Tt?R|)c4gkKp9obP3+>M4>s(BrV)rM6bxc{f~ZBvj`n?FC~TW_D3H z`@F1<8`F&Vjxt;)7#7W)EW%l8Yw=!?iE8owyKl=$m@}LE(7FxQQVUilElNNLbDj7a zazjq(`y3Jk$_P=p2DqRuOiEn^>r9qnkj;rS0W%z^s_WDMej}`l>q%_C*altUw~`+m zT!>^JCqb?!5?X+rD_AtLRM9>J>YIK_6v#0{M^(zN#ggoOpk|!TSy)vM7kZ{1XkX_X z87dBEFUZ4xV#mq~O|b@x96QO-QqTg1WOca}Z9cGw&V|g@JbTJ1HLme81nZz>z1{OG z(m-sK0@2J`UMv3k%4f|%&wi%Y(im9!j2`u&SsaWYvPJOqcnJJ6_bZ6C>I9#>`c#-z zIVc!+mK?7VqQ!8tIDTAGYz+Kv47JVm)XBs8cLR|0PVwaS$U%MgfU`ZjE#-9~&S@-; zRc^yuK%KOE`T<bEUsE@yI~v7Du+xUTo2w3IwxX$8Y$-?1u1jJlUlT?Pp`u>qDPE3|$wi7?EV14Yw2pN*ir_zb z_6u#)%RwDm=$Nk!0>J+vYu-62vB-6{+N2DNCbgtvVTN5U!)4;0jL@A?oz zRS?O7_d)^*lVF{~?>bQAPS`=^W_lbh5_)CAy8+fYvo$+V1SqNdRo!)b!HY$y%Pr20 zM7jc8K^$tX%VtiV94RO zQJNHYv;&o2LqLnPDRcA&u*QD*)UY{RkT?ve`PVZ?h~o!JGpU#Eum zGEC=X6qpP7__JRmf=uD24fu6bsf|zwFVg16qwj|5X6lY0wR!X49qWS2b z!KW@)<%jNDCGgrWA+t~m%!{>A+SNTC+q`C1^borW)|pSpQ3&)V^+eT)t;J%3g94%I z)0NQWfEn(c^>kwuED+QJVUI01yUmv~7P7&8D6Y0p;pS`HUhP*<SrnR|P)UZS1!Y{M2$! zx8RVP7SZ%xwphcz3iRSszE!XW%Pc?qeec<6`4{+3UE0yLA-;ePQe&^0I2wz;H~fkGQf9}R8f3Vfc1 zh~?|^L7Xd_p|rMCHI?OCN8SHg=G^J529uOFD7}dU2a$RkQBT!!8_Pb6S?VvC_1vh+ zj?4I#O2Uv%?<7(YM#hgA{kEb2VyjIox$_+xsq^Z*V*He;9pZCA$70vhtTZy}R93t) z5jPdC^2M>_9#dDilN6aXKAU%RQ4aJ|kUcofwCCn^ zgy%?q9fkQ@9xi`Z&|9>`WDB>${XwP+mm$iL-7(JcE|_Jvjs={&wPIp)MvYe zEAP}PhGsY5?o)rQM(g!t-V*W}3*-6#Uc<3olv3^=x0qf=xq?3A_-VUMj`dN+68<*FQY;df*xrTbEN9T1vuqVg*QR>8b z-OmPgJC4}n$ diff --git a/doc/pics/threshold.png b/doc/pics/threshold.png deleted file mode 100644 index 2e1bfdf3146f663f98f112b7410644fc5d80140d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4474 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 diff --git a/doc/pics/tsukuba_l.png b/doc/pics/tsukuba_l.png deleted file mode 100644 index be22fd69425172e3e75c3f12d4832c672f26d9de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 85192 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�i!{H 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 &blobDetector = new SimpleBlobDetector() ) +.. ocv:pyfunction:: cv2.findCirclesGridDefault(image, patternSize[, centers[, flags]]) -> centers + :param image: Grid view of source circles. It must be an 8-bit grayscale or color image. :param patternSize: Number of circles per a grid row and column ``( patternSize = Size(points_per_row, points_per_colum) )`` . @@ -757,7 +752,24 @@ Computes an optimal affine transformation between two 3D point sets. The function estimates an optimal 3D affine transformation between two 3D point sets using the RANSAC algorithm. +filterSpeckles +-------------- +Filters off small noise blobs (speckles) in the disparity map +.. ocv:function:: void filterSpeckles( InputOutputArray img, double newVal, int maxSpeckleSize, double maxDiff, InputOutputArray buf=noArray() ); + +.. ocv:pyfunction:: cv2.filterSpeckles(img, newVal, maxSpeckleSize, maxDiff[, buf]) -> None + + :param img: The input 16-bit signed disparity image + + :param newVal: The disparity value used to paint-off the speckles + + :param maxSpeckleSize: The maximum speckle size to consider it a speckle. Larger blobs are not affected by the algorithm + + :param maxDiff: Maximum difference between neighbor disparity pixels to put them into the same blob. Note that since StereoBM, StereoSGBM and may be other algorithms return a fixed-point disparity map, where disparity values are multiplied by 16, this scale factor should be taken into account when specifying this parameter value. + + :param buf: The optional temporary buffer to avoid memory allocation within the function. + getOptimalNewCameraMatrix ----------------------------- @@ -786,8 +798,8 @@ Returns the new camera matrix based on the free scaling parameter. The function computes and returns the optimal new camera matrix based on the free scaling parameter. By varying this parameter, you may retrieve only sensible pixels ``alpha=0`` , keep all the original image pixels if there is valuable information in the corners ``alpha=1`` , or get something in between. When ``alpha>0`` , the undistortion result is likely to have some black pixels corresponding to "virtual" pixels outside of the captured distorted image. The original camera matrix, distortion coefficients, the computed new camera matrix, and ``newImageSize`` should be passed to -:ocv:func:`InitUndistortRectifyMap` to produce the maps for -:ocv:func:`Remap` . +:ocv:func:`initUndistortRectifyMap` to produce the maps for +:ocv:func:`remap` . @@ -1047,6 +1059,8 @@ The constructors. The constructors initialize ``StereoBM`` state. You can then call ``StereoBM::operator()`` to compute disparity for a specific stereo pair. +.. note:: In the C API you need to deallocate ``CvStereoBM`` state when it is not needed anymore using ``cvReleaseStereoBMState(&stereobm)``. + StereoBM::operator() ----------------------- Computes disparity using the BM algorithm for a rectified stereo pair. @@ -1299,7 +1313,7 @@ stereoRectify :param alpha: Free scaling parameter. If it is -1 or absent, the function performs the default scaling. Otherwise, the parameter should be between 0 and 1. ``alpha=0`` means that the rectified images are zoomed and shifted so that only valid pixels are visible (no black areas after rectification). ``alpha=1`` means that the rectified image is decimated and shifted so that all the pixels from the original images from the cameras are retained in the rectified images (no source image pixels are lost). Obviously, any intermediate value yields an intermediate result between those two extreme cases. - :param newImageSize: New image resolution after rectification. The same size should be passed to :ref:`InitUndistortRectifyMap` (see the ``stereo_calib.cpp`` sample in OpenCV samples directory). When (0,0) is passed (default), it is set to the original ``imageSize`` . Setting it to larger value can help you preserve details in the original image, especially when there is a big radial distortion. + :param newImageSize: New image resolution after rectification. The same size should be passed to :ocv:func:`initUndistortRectifyMap` (see the ``stereo_calib.cpp`` sample in OpenCV samples directory). When (0,0) is passed (default), it is set to the original ``imageSize`` . Setting it to larger value can help you preserve details in the original image, especially when there is a big radial distortion. :param roi1, roi2: Optional output rectangles inside the rectified images where all the pixels are valid. If ``alpha=0`` , the ROIs cover the whole images. Otherwise, they are likely to be smaller (see the picture below). @@ -1338,7 +1352,7 @@ The function computes the rotation matrices for each camera that (virtually) mak As you can see, the first three columns of ``P1`` and ``P2`` will effectively be the new "rectified" camera matrices. The matrices, together with ``R1`` and ``R2`` , can then be passed to -:ocv:func:`InitUndistortRectifyMap` to initialize the rectification map for each camera. +:ocv:func:`initUndistortRectifyMap` to initialize the rectification map for each camera. See below the screenshot from the ``stereo_calib.cpp`` sample. Some red horizontal lines pass through the corresponding image regions. This means that the images are well rectified, which is what most stereo correspondence algorithms rely on. The green rectangles are ``roi1`` and ``roi2`` . You see that their interiors are all valid pixels. @@ -1369,12 +1383,14 @@ stereoRectifyUncalibrated The function computes the rectification transformations without knowing intrinsic parameters of the cameras and their relative position in the space, which explains the suffix "uncalibrated". Another related difference from :ocv:func:`StereoRectify` is that the function outputs not the rectification transformations in the object (3D) space, but the planar perspective transformations encoded by the homography matrices ``H1`` and ``H2`` . The function implements the algorithm -Hartley99 -. +[Hartley99]_. .. note:: - While the algorithm does not need to know the intrinsic parameters of the cameras, it heavily depends on the epipolar geometry. Therefore, if the camera lenses have a significant distortion, it would be better to correct it before computing the fundamental matrix and calling this function. For example, distortion coefficients can be estimated for each head of stereo camera separately by using - :ocv:func:`calibrateCamera` . Then, the images can be corrected using - :ocv:func:`undistort` , or just the point coordinates can be corrected with - :ocv:func:`undistortPoints` . + While the algorithm does not need to know the intrinsic parameters of the cameras, it heavily depends on the epipolar geometry. Therefore, if the camera lenses have a significant distortion, it would be better to correct it before computing the fundamental matrix and calling this function. For example, distortion coefficients can be estimated for each head of stereo camera separately by using :ocv:func:`calibrateCamera` . Then, the images can be corrected using :ocv:func:`undistort` , or just the point coordinates can be corrected with :ocv:func:`undistortPoints` . + +.. [BouguetMCT] J.Y.Bouguet. MATLAB calibration tool. http://www.vision.caltech.edu/bouguetj/calib_doc/ + +.. [Hartley99] Hartley, R.I., “Theory and Practice of Projective Rectification”. IJCV 35 2, pp 115-127 (1999) + +.. [Zhang2000] Z. Zhang. A Flexible New Technique for Camera Calibration. IEEE Transactions on Pattern Analysis and Machine Intelligence, 22(11):1330-1334, 2000. \ No newline at end of file diff --git a/modules/core/doc/clustering.rst b/modules/core/doc/clustering.rst index 804efb16d1..e37036aae3 100644 --- a/modules/core/doc/clustering.rst +++ b/modules/core/doc/clustering.rst @@ -29,7 +29,7 @@ Finds centers of clusters and groups input samples around the clusters. * **KMEANS_RANDOM_CENTERS** Select random initial centers in each attempt. - * **KMEANS_PP_CENTERS** Use ``kmeans++`` center initialization by Arthur and Vassilvitskii. + * **KMEANS_PP_CENTERS** Use ``kmeans++`` center initialization by Arthur and Vassilvitskii [Arthur2007]. * **KMEANS_USE_INITIAL_LABELS** 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. @@ -76,3 +76,4 @@ http://en.wikipedia.org/wiki/Disjoint-set_data_structure . The function returns the number of equivalency classes. +.. [Arthur2007] Arthur and S. Vassilvitskii “k-means++: the advantages of careful seeding”, Proceedings of the eighteenth annual ACM-SIAM symposium on Discrete algorithms, 2007 diff --git a/modules/core/doc/core.rst b/modules/core/doc/core.rst index b510e458fa..7eb4e3e63a 100644 --- a/modules/core/doc/core.rst +++ b/modules/core/doc/core.rst @@ -6,9 +6,12 @@ core. The Core Functionality :maxdepth: 2 basic_structures + old_basic_structures + dynamic_structures operations_on_arrays drawing_functions xml_yaml_persistence + old_xml_yaml_persistence clustering utility_and_system_functions_and_macros diff --git a/modules/core/doc/drawing_functions.rst b/modules/core/doc/drawing_functions.rst index c86420f712..29f5527dc4 100644 --- a/modules/core/doc/drawing_functions.rst +++ b/modules/core/doc/drawing_functions.rst @@ -91,6 +91,9 @@ Draws a simple or thick elliptic arc or fills an ellipse sector. .. ocv:cfunction:: void cvEllipse( CvArr* img, CvPoint center, CvSize axes, double angle, double startAngle, double endAngle, CvScalar color, int thickness=1, int lineType=8, int shift=0 ) .. ocv:pyoldfunction:: cv.Ellipse(img, center, axes, angle, startAngle, endAngle, color, thickness=1, lineType=8, shift=0)-> None +.. ocv:cfunction:: void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color, int thickness=1, int lineType=8, int shift=0 ) +.. ocv:pyoldfunction:: cv.EllipseBox(img, box, color, thickness=1, lineType=8, shift=0)-> None + :param img: Image. :param center: Center of the ellipse. @@ -103,7 +106,7 @@ Draws a simple or thick elliptic arc or fills an ellipse sector. :param endAngle: Ending angle of the elliptic arc in degrees. - :param box: Alternative ellipse representation via :ocv:class:`RotatedRect`. This means that the function draws an ellipse inscribed in the rotated rectangle. + :param box: Alternative ellipse representation via :ocv:class:`RotatedRect` or ``CvBox2D``. This means that the function draws an ellipse inscribed in the rotated rectangle. :param color: Ellipse color. @@ -264,6 +267,54 @@ That is, the following code renders some text, the tight box surrounding it, and Scalar::all(255), thickness, 8); +InitFont +-------- +Initializes font structure (OpenCV 1.x API). + +.. cfunction:: void cvInitFont( CvFont* font, int fontFace, double hscale, double vscale, double shear=0, int thickness=1, int lineType=8 ) + + :param font: Pointer to the font structure initialized by the function + + :param fontFace: Font name identifier. Only a subset of Hershey fonts http://sources.isc.org/utils/misc/hershey-font.txt are supported now: + + * **CV_FONT_HERSHEY_SIMPLEX** normal size sans-serif font + + * **CV_FONT_HERSHEY_PLAIN** small size sans-serif font + + * **CV_FONT_HERSHEY_DUPLEX** normal size sans-serif font (more complex than ``CV_FONT_HERSHEY_SIMPLEX`` ) + + * **CV_FONT_HERSHEY_COMPLEX** normal size serif font + + * **CV_FONT_HERSHEY_TRIPLEX** normal size serif font (more complex than ``CV_FONT_HERSHEY_COMPLEX`` ) + + * **CV_FONT_HERSHEY_COMPLEX_SMALL** smaller version of ``CV_FONT_HERSHEY_COMPLEX`` + + * **CV_FONT_HERSHEY_SCRIPT_SIMPLEX** hand-writing style font + + * **CV_FONT_HERSHEY_SCRIPT_COMPLEX** more complex variant of ``CV_FONT_HERSHEY_SCRIPT_SIMPLEX`` + + The parameter can be composited from one of the values above and an optional ``CV_FONT_ITALIC`` flag, which indicates italic or oblique font. + + + :param hscale: Horizontal scale. If equal to ``1.0f`` , the characters have the original width depending on the font type. If equal to ``0.5f`` , the characters are of half the original width. + + + :param vscale: Vertical scale. If equal to ``1.0f`` , the characters have the original height depending on the font type. If equal to ``0.5f`` , the characters are of half the original height. + + + :param shear: Approximate tangent of the character slope relative to the vertical line. A zero value means a non-italic font, ``1.0f`` means about a 45 degree slope, etc. + + + :param thickness: Thickness of the text strokes + + + :param lineType: Type of the strokes, see :ref:`Line` description + + +The function initializes the font structure that can be passed to text rendering functions. + +.. seealso:: :ocv:cfunc:`PutText` + line -------- @@ -428,6 +479,8 @@ Draws a text string. :param org: Bottom-left corner of the text string in the image. + :param font: ``CvFont`` structure initialized using :ocv:cfunc:`InitFont`. + :param fontFace: Font type. One of ``FONT_HERSHEY_SIMPLEX``, ``FONT_HERSHEY_PLAIN``, ``FONT_HERSHEY_DUPLEX``, ``FONT_HERSHEY_COMPLEX``, ``FONT_HERSHEY_TRIPLEX``, ``FONT_HERSHEY_COMPLEX_SMALL``, ``FONT_HERSHEY_SCRIPT_SIMPLEX``, or ``FONT_HERSHEY_SCRIPT_COMPLEX``, where each of the font ID's can be combined with ``FONT_HERSHEY_ITALIC`` to get the slanted letters. diff --git a/modules/core/doc/dynamic_structures.rst b/modules/core/doc/dynamic_structures.rst new file mode 100644 index 0000000000..a92f95e2a3 --- /dev/null +++ b/modules/core/doc/dynamic_structures.rst @@ -0,0 +1,1549 @@ +Dynamic Structures +================== + +.. highlight:: c + +The section describes OpenCV 1.x API for creating growable sequences and other dynamic data structures allocated in ``CvMemStorage``. If you use the new C++, Python, Java etc interface, you will unlikely need this functionality. Use ``std::vector`` or other high-level data structures. + +CvMemStorage +------------ + +.. ocv:struct:: CvMemStorage + +A storage for various OpenCV dynamic data structures, such as ``CvSeq``, ``CvSet`` etc. + + .. ocv:member:: CvMemBlock* bottom + + the first memory block in the double-linked list of blocks + + .. ocv:member:: CvMemBlock* top + + the current partially allocated memory block in the list of blocks + + .. ocv:member:: CvMemStorage* parent + + the parent storage (if any) from which the new memory blocks are borrowed. + + .. ocv:member:: int free_space + + number of free bytes in the ``top`` block + + .. ocv:member:: int block_size + + the total size of the memory blocks + +Memory storage is a low-level structure used to store dynamically growing data structures such as sequences, contours, graphs, subdivisions, etc. It is organized as a list of memory blocks of equal size - +``bottom`` field is the beginning of the list of blocks and ``top`` is the currently used block, but not necessarily the last block of the list. All blocks between ``bottom`` and ``top``, not including the +latter, are considered fully occupied; all blocks between ``top`` and the last block, not including ``top``, are considered free and ``top`` itself is partly ocupied - ``free_space`` contains the number of free bytes left in the end of ``top``. + +A new memory buffer that may be allocated explicitly by :ocv:cfunc:`MemStorageAlloc` function or implicitly by higher-level functions, such as :ocv:cfunc:`SeqPush`, :ocv:cfunc:`GraphAddEdge` etc. + +The buffer is put in the end of already allocated space in the ``top`` memory block, if there is enough free space. After allocation, ``free_space`` is decreased by the size of the allocated buffer plus some padding to keep the proper alignment. When the allocated buffer does not fit into the available portion of +``top``, the next storage block from the list is taken as ``top`` and ``free_space`` is reset to the whole block size prior to the allocation. + +If there are no more free blocks, a new block is allocated (or borrowed from the parent, see :ocv:cfunc:`CreateChildMemStorage`) and added to the end of list. Thus, the storage behaves as a stack with ``bottom`` indicating bottom of the stack and the pair (``top``, ``free_space``) +indicating top of the stack. The stack top may be saved via :ocv:cfunc:`SaveMemStoragePos`, restored via +:ocv:cfunc:`RestoreMemStoragePos`, or reset via :ocv:cfunc:`ClearStorage`. + +CvMemBlock +---------- + +.. ocv:struct:: CvMemBlock + +The structure :ocv:struct:`CvMemBlock` represents a single block of memory storage. The actual data in the memory blocks follows the header. + +CvMemStoragePos +--------------- + +.. ocv:struct:: CvMemStoragePos + +The structure stores the position in the memory storage. It is used by :ocv:cfunc:`SaveMemStoragePos` and :ocv:cfunc:`RestoreMemStoragePos`. + +CvSeq +----- + +.. ocv:struct:: CvSeq + +Dynamically growing sequence. + + .. ocv:member:: int flags + + sequence flags, including the sequence signature (CV_SEQ_MAGIC_VAL or CV_SET_MAGIC_VAL), type of the elements and some other information about the sequence. + + .. ocv:member:: int header_size + + size of the sequence header. It should be sizeof(CvSeq) at minimum. See :ocv:cfunc:`CreateSeq`. + + .. ocv:member:: CvSeq* h_prev + .. ocv:member:: CvSeq* h_next + .. ocv:member:: CvSeq* v_prev + .. ocv:member:: CvSeq* v_next + + pointers to another sequences in a sequence tree. Sequence trees are used to store hierarchical contour structures, retrieved by :ocv:cfunc:`FindContours` + + .. ocv:member:: int total + + the number of sequence elements + + .. ocv:member:: int elem_size + + size of each sequence element in bytes + + .. ocv:member:: CvMemStorage* storage + + memory storage where the sequence resides. It can be a NULL pointer. + + .. ocv:member:: CvSeqBlock* first + + pointer to the first data block + +The structure ``CvSeq`` is a base for all of OpenCV dynamic data structures. +There are two types of sequences - dense and sparse. The base type for dense +sequences is :ocv:struct:`CvSeq` and such sequences are used to represent +growable 1d arrays - vectors, stacks, queues, and deques. They have no gaps +in the middle - if an element is removed from the middle or inserted +into the middle of the sequence, the elements from the closer end are +shifted. Sparse sequences have :ocv:struct:`CvSet` as a base class and they are +discussed later in more detail. They are sequences of nodes; each may be either occupied or free as indicated by the node flag. Such sequences are used for unordered data structures such as sets of elements, graphs, hash tables and so forth. + + +CvSlice +------- + +.. ocv:struct:: CvSlice + +A sequence slice. In C++ interface the class :ocv:class:`Range` should be used instead. + + .. ocv:member: int start_index + + inclusive start index of the sequence slice + + .. ocv:member: int end_index + + exclusive end index of the sequence slice + +There are helper functions to construct the slice and to compute its length: :: + + inline CvSlice cvSlice( int start, int end ); + #define CV_WHOLE_SEQ_END_INDEX 0x3fffffff + #define CV_WHOLE_SEQ cvSlice(0, CV_WHOLE_SEQ_END_INDEX) + + /* calculates the sequence slice length */ + int cvSliceLength( CvSlice slice, const CvSeq* seq ); + +.. + +Some of functions that operate on sequences take a ``CvSlice slice`` parameter that is often set to the whole sequence (CV_WHOLE_SEQ) by default. Either of the ``start_index`` and ``end_index`` may be negative or exceed the sequence length. If they are equal, the slice is considered empty (i.e., contains no elements). Because sequences are treated as circular structures, the slice may select a +few elements in the end of a sequence followed by a few elements at the beginning of the sequence. For example, ``cvSlice(-2, 3)`` in the case of a 10-element sequence will select a 5-element slice, containing the pre-last (8th), last (9th), the very first (0th), second (1th) and third (2nd) +elements. The functions normalize the slice argument in the following way: + + #. :ocv:cfunc:`SliceLength` is called to determine the length of the slice, + #. ``start_index`` of the slice is normalized similarly to the argument of :ocv:cfunc:`GetSeqElem` (i.e., negative indices are allowed). The actual slice to process starts at the normalized ``start_index`` and lasts :ocv:cfunc:`SliceLength` elements (again, assuming the sequence is a circular structure). + +If a function does not accept a slice argument, but you want to process only a part of the sequence, the sub-sequence may be extracted using the :ocv:cfunc:`SeqSlice` function, or stored into a continuous +buffer with :ocv:cfunc:`CvtSeqToArray` (optionally, followed by :ocv:cfunc:`MakeSeqHeaderForArray`). + +CvSet +----- + +.. ocv:struct:: CvSet + +The structure ``CvSet`` is a base for OpenCV 1.x sparse data structures. It is derived from :ocv:struct:`CvSeq` and includes an additional member ``free_elems`` - a list of free nodes. Every node of the set, whether free or not, is an element of the underlying sequence. While there are no restrictions on elements of dense sequences, the set (and derived structures) elements must start with an integer field and be able to fit CvSetElem structure, because these two fields (an integer followed by a pointer) are required for the organization of a node set with the list of free nodes. If a node is free, the ``flags`` +field is negative (the most-significant bit, or MSB, of the field is set), and the ``next_free`` points to the next free node (the first free node is referenced by the ``free_elems`` field of :ocv:struct:`CvSet`). And if a node is occupied, the ``flags`` field is positive and contains the node index that may be retrieved using the (``set_elem->flags & CV_SET_ELEM_IDX_MASK``) expressions, the rest of the node content is determined by the user. In particular, the occupied nodes are not linked as the free nodes are, so the second field can be used for such a link as well as for some different purpose. The macro ``CV_IS_SET_ELEM(set_elem_ptr)`` can be used to determined whether the specified node is occupied or not. + +Initially the set and the free node list are empty. When a new node is requested from the set, it is taken from the list of free nodes, which is then updated. If the list appears to be empty, a new sequence block is allocated and all the nodes within the block are joined in the list of free nodes. Thus, the ``total`` +field of the set is the total number of nodes both occupied and free. When an occupied node is released, it is added to the list of free nodes. The node released last will be occupied first. + +``CvSet`` is used to represent graphs (:ocv:struct:`CvGraph`), sparse multi-dimensional arrays (:ocv:struct:`CvSparseMat`), and planar subdivisions (:ocv:struct:`CvSubdiv2D`). + + +CvGraph +------- +.. ocv:struct:: CvGraph + +The structure ``CvGraph`` is a base for graphs used in OpenCV 1.x. It inherits from +:ocv:struct:`CvSet`, that is, it is considered as a set of vertices. Besides, it contains another set as a member, a set of graph edges. Graphs in OpenCV are represented using adjacency lists format. + + +CvGraphScanner +-------------- + +.. ocv:struct:: CvGraphScanner + +The structure ``CvGraphScanner`` is used for depth-first graph traversal. See discussion of the functions below. + + +CvTreeNodeIterator +------------------ + +The structure ``CvTreeNodeIterator`` is used to traverse trees of sequences. + +ClearGraph +---------- +Clears a graph. + +.. ocv:cfunction:: void cvClearGraph( CvGraph* graph ) + + :param graph: Graph + +The function removes all vertices and edges from a graph. The function has O(1) time complexity. + +ClearMemStorage +--------------- +Clears memory storage. + +.. ocv:cfunction:: void cvClearMemStorage( CvMemStorage* storage ) + + :param storage: Memory storage + +The function resets the top (free space boundary) of the storage to the very beginning. This function does not deallocate any memory. If the storage has a parent, the function returns +all blocks to the parent. + +ClearSeq +-------- +Clears a sequence. + +.. ocv:cfunction:: void cvClearSeq( CvSeq* seq ) + + :param seq: Sequence + +The function removes all elements from a sequence. The function does not return the memory to the storage block, but this memory is reused later when new elements are added to the sequence. The function has +'O(1)' time complexity. + +.. note:: It is impossible to deallocate a sequence, i.e. free space in the memory storage occupied by the sequence. Instead, call :ocv:cfunc:`ClearMemStorage` or :ocv:cfunc:`ReleaseMemStorage` from time to time somewhere in a top-level processing loop. + +ClearSet +-------- +Clears a set. + +.. ocv:cfunction:: void cvClearSet( CvSet* setHeader ) + + :param setHeader: Cleared set + +The function removes all elements from set. It has O(1) time complexity. + +CloneGraph +---------- +Clones a graph. + +.. ocv:cfunction:: CvGraph* cvCloneGraph( const CvGraph* graph, CvMemStorage* storage ) + + :param graph: The graph to copy + + :param storage: Container for the copy + +The function creates a full copy of the specified graph. If the +graph vertices or edges have pointers to some external data, it can still be +shared between the copies. The vertex and edge indices in the new graph +may be different from the original because the function defragments +the vertex and edge sets. + +CloneSeq +-------- +Creates a copy of a sequence. + +.. ocv:cfunction:: CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage=NULL ) +.. ocv:pyoldfunction:: cv.CloneSeq(seq, storage)-> None + + :param seq: Sequence + + :param storage: The destination storage block to hold the new sequence header and the copied data, if any. If it is NULL, the function uses the storage block containing the input sequence. + +The function makes a complete copy of the input sequence and returns it. + +The call ``cvCloneSeq( seq, storage )`` is equivalent to ``cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 )``. + + +CreateChildMemStorage +--------------------- +Creates child memory storage. + +.. ocv:cfunction:: CvMemStorage* cvCreateChildMemStorage(CvMemStorage* parent) + + :param parent: Parent memory storage + +The function creates a child memory +storage that is similar to simple memory storage except for the +differences in the memory allocation/deallocation mechanism. When a +child storage needs a new block to add to the block list, it tries +to get this block from the parent. The first unoccupied parent block +available is taken and excluded from the parent block list. If no blocks +are available, the parent either allocates a block or borrows one from +its own parent, if any. In other words, the chain, or a more complex +structure, of memory storages where every storage is a child/parent of +another is possible. When a child storage is released or even cleared, +it returns all blocks to the parent. In other aspects, child storage +is the same as simple storage. + +Child storage is useful in the following situation. Imagine +that the user needs to process dynamic data residing in a given storage area and +put the result back to that same storage area. With the simplest approach, +when temporary data is resided in the same storage area as the input and +output data, the storage area will look as follows after processing: + +Dynamic data processing without using child storage + +.. image:: pics/memstorage1.png + +That is, garbage appears in the middle of the storage. However, if +one creates a child memory storage at the beginning of processing, +writes temporary data there, and releases the child storage at the end, +no garbage will appear in the source/destination storage: + +Dynamic data processing using a child storage + +.. image:: pics/memstorage2.png + +CreateGraph +----------- +Creates an empty graph. + +.. ocv:cfunction:: CvGraph* cvCreateGraph( int graph_flags, int header_size, int vtx_size, int edge_size, CvMemStorage* storage ) + + + :param graph_flags: Type of the created graph. Usually, it is either ``CV_SEQ_KIND_GRAPH`` for generic unoriented graphs and ``CV_SEQ_KIND_GRAPH | CV_GRAPH_FLAG_ORIENTED`` for generic oriented graphs. + + :param header_size: Graph header size; may not be less than ``sizeof(CvGraph)`` + + :param vtx_size: Graph vertex size; the custom vertex structure must start with :ocv:struct:`CvGraphVtx` (use ``CV_GRAPH_VERTEX_FIELDS()`` ) + + :param edge_size: Graph edge size; the custom edge structure must start with :ocv:struct:`CvGraphEdge` (use ``CV_GRAPH_EDGE_FIELDS()`` ) + + :param storage: The graph container + +The function creates an empty graph and returns a pointer to it. + +CreateGraphScanner +------------------ +Creates structure for depth-first graph traversal. + +.. ocv:cfunction:: CvGraphScanner* cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx=NULL, int mask=CV_GRAPH_ALL_ITEMS ) + + + :param graph: Graph + + :param vtx: Initial vertex to start from. If NULL, the traversal starts from the first vertex (a vertex with the minimal index in the sequence of vertices). + + :param mask: Event mask indicating which events are of interest to the user (where :ocv:cfunc:`NextGraphItem` function returns control to the user) It can be ``CV_GRAPH_ALL_ITEMS`` (all events are of interest) or a combination of the following flags: + + * **CV_GRAPH_VERTEX** stop at the graph vertices visited for the first time + + * **CV_GRAPH_TREE_EDGE** stop at tree edges ( ``tree edge`` is the edge connecting the last visited vertex and the vertex to be visited next) + + * **CV_GRAPH_BACK_EDGE** stop at back edges ( ``back edge`` is an edge connecting the last visited vertex with some of its ancestors in the search tree) + + * **CV_GRAPH_FORWARD_EDGE** stop at forward edges ( ``forward edge`` is an edge conecting the last visited vertex with some of its descendants in the search tree. The forward edges are only possible during oriented graph traversal) + + * **CV_GRAPH_CROSS_EDGE** stop at cross edges ( ``cross edge`` is an edge connecting different search trees or branches of the same tree. The ``cross edges`` are only possible during oriented graph traversal) + + * **CV_GRAPH_ANY_EDGE** stop at any edge ( ``tree, back, forward`` , and ``cross edges`` ) + + * **CV_GRAPH_NEW_TREE** stop in the beginning of every new search tree. When the traversal procedure visits all vertices and edges reachable from the initial vertex (the visited vertices together with tree edges make up a tree), it searches for some unvisited vertex in the graph and resumes the traversal process from that vertex. Before starting a new tree (including the very first tree when ``cvNextGraphItem`` is called for the first time) it generates a ``CV_GRAPH_NEW_TREE`` event. For unoriented graphs, each search tree corresponds to a connected component of the graph. + + * **CV_GRAPH_BACKTRACKING** stop at every already visited vertex during backtracking - returning to already visited vertexes of the traversal tree. + +The function creates a structure for depth-first graph traversal/search. The initialized structure is used in the +:ocv:cfunc:`NextGraphItem` +function - the incremental traversal procedure. + +CreateMemStorage +---------------- +Creates memory storage. + +.. ocv:cfunction:: CvMemStorage* cvCreateMemStorage( int blockSize=0 ) +.. ocv:pyoldfunction:: cv.CreateMemStorage(blockSize=0) -> memstorage + + + :param blockSize: Size of the storage blocks in bytes. If it is 0, the block size is set to a default value - currently it is about 64K. + +The function creates an empty memory storage. See +:ocv:struct:`CvMemStorage` +description. + +CreateSeq +--------- +Creates a sequence. + +.. ocv:cfunction:: CvSeq* cvCreateSeq( int seqFlags, int headerSize, int elemSize, CvMemStorage* storage) + + + :param seqFlags: Flags of the created sequence. If the sequence is not passed to any function working with a specific type of sequences, the sequence value may be set to 0, otherwise the appropriate type must be selected from the list of predefined sequence types. + + :param headerSize: Size of the sequence header; must be greater than or equal to ``sizeof(CvSeq)`` . If a specific type or its extension is indicated, this type must fit the base type header. + + :param elemSize: Size of the sequence elements in bytes. The size must be consistent with the sequence type. For example, for a sequence of points to be created, the element type ``CV_SEQ_ELTYPE_POINT`` should be specified and the parameter ``elemSize`` must be equal to ``sizeof(CvPoint)`` . + + :param storage: Sequence location + +The function creates a sequence and returns +the pointer to it. The function allocates the sequence header in +the storage block as one continuous chunk and sets the structure +fields +``flags`` +, +``elemSize`` +, +``headerSize`` +, and +``storage`` +to passed values, sets +``delta_elems`` +to the +default value (that may be reassigned using the +:ocv:cfunc:`SetSeqBlockSize` +function), and clears other header fields, including the space following +the first +``sizeof(CvSeq)`` +bytes. + +CreateSet +--------- +Creates an empty set. + +.. ocv:cfunction:: CvSet* cvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage* storage ) + + :param set_flags: Type of the created set + + :param header_size: Set header size; may not be less than ``sizeof(CvSet)`` + + :param elem_size: Set element size; may not be less than :ocv:struct:`CvSetElem` + + :param storage: Container for the set + +The function creates an empty set with a specified header size and element size, and returns the pointer to the set. This function is just a thin layer on top of +:ocv:cfunc:`CreateSeq`. + +CvtSeqToArray +------------- +Copies a sequence to one continuous block of memory. + +.. ocv:cfunction:: void* cvCvtSeqToArray( const CvSeq* seq, void* elements, CvSlice slice=CV_WHOLE_SEQ ) + + :param seq: Sequence + + :param elements: Pointer to the destination array that must be large enough. It should be a pointer to data, not a matrix header. + + :param slice: The sequence portion to copy to the array + +The function copies the entire sequence or subsequence to the specified buffer and returns the pointer to the buffer. + +EndWriteSeq +----------- +Finishes the process of writing a sequence. + +.. ocv:cfunction:: CvSeq* cvEndWriteSeq( CvSeqWriter* writer ) + + :param writer: Writer state + +The function finishes the writing process and +returns the pointer to the written sequence. The function also truncates +the last incomplete sequence block to return the remaining part of the +block to memory storage. After that, the sequence can be read and +modified safely. See +:ocv:cfunc:`StartWriteSeq` +and +:ocv:cfunc:`StartAppendToSeq` + +FindGraphEdge +------------- +Finds an edge in a graph. + +.. ocv:cfunction:: CvGraphEdge* cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ) + +:: + + #define cvGraphFindEdge cvFindGraphEdge + +.. + + :param graph: Graph + + :param start_idx: Index of the starting vertex of the edge + + :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + +The function finds the graph edge connecting two specified vertices and returns a pointer to it or NULL if the edge does not exist. + +FindGraphEdgeByPtr +------------------ +Finds an edge in a graph by using its pointer. + +.. ocv:cfunction:: CvGraphEdge* cvFindGraphEdgeByPtr( const CvGraph* graph, const CvGraphVtx* startVtx, const CvGraphVtx* endVtx ) + +:: + + #define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr + +.. + + :param graph: Graph + + :param startVtx: Pointer to the starting vertex of the edge + + :param endVtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + +The function finds the graph edge connecting two specified vertices and returns pointer to it or NULL if the edge does not exists. + +FlushSeqWriter +-------------- +Updates sequence headers from the writer. + +.. ocv:cfunction:: void cvFlushSeqWriter( CvSeqWriter* writer ) + + :param writer: Writer state + +The function is intended to enable the user to +read sequence elements, whenever required, during the writing process, +e.g., in order to check specific conditions. The function updates the +sequence headers to make reading from the sequence possible. The writer +is not closed, however, so that the writing process can be continued at +any time. If an algorithm requires frequent flushes, consider using +:ocv:cfunc:`SeqPush` +instead. + +GetGraphVtx +----------- +Finds a graph vertex by using its index. + +.. ocv:cfunction:: CvGraphVtx* cvGetGraphVtx( CvGraph* graph, int vtx_idx ) + + :param graph: Graph + + :param vtx_idx: Index of the vertex + +The function finds the graph vertex by using its index and returns the pointer to it or NULL if the vertex does not belong to the graph. + +GetSeqElem +---------- +Returns a pointer to a sequence element according to its index. + +.. ocv:cfunction:: char* cvGetSeqElem( const CvSeq* seq, int index ) + +:: + + #define CV_GET_SEQ_ELEM( TYPE, seq, index ) (TYPE*)cvGetSeqElem( (CvSeq*)(seq), (index) ) + +.. + + :param seq: Sequence + + :param index: Index of element + +The function finds the element with the given +index in the sequence and returns the pointer to it. If the element +is not found, the function returns 0. The function supports negative +indices, where -1 stands for the last sequence element, -2 stands for +the one before last, etc. If the sequence is most likely to consist of +a single sequence block or the desired element is likely to be located +in the first block, then the macro +``CV_GET_SEQ_ELEM( elemType, seq, index )`` +should be used, where the parameter +``elemType`` +is the +type of sequence elements ( +:ocv:struct:`CvPoint` +for example), the parameter +``seq`` +is a sequence, and the parameter +``index`` +is the index +of the desired element. The macro checks first whether the desired element +belongs to the first block of the sequence and returns it if it does; +otherwise the macro calls the main function +``GetSeqElem`` +. Negative +indices always cause the +:ocv:cfunc:`GetSeqElem` +call. The function has O(1) +time complexity assuming that the number of blocks is much smaller than the +number of elements. + +GetSeqReaderPos +--------------- +Returns the current reader position. + +.. ocv:cfunction:: int cvGetSeqReaderPos( CvSeqReader* reader ) + + :param reader: Reader state + +The function returns the current reader position (within 0 ... +``reader->seq->total`` +- 1). + +GetSetElem +---------- +Finds a set element by its index. + +.. ocv:cfunction:: CvSetElem* cvGetSetElem( const CvSet* setHeader, int index ) + + :param setHeader: Set + + :param index: Index of the set element within a sequence + +The function finds a set element by its index. The function returns the pointer to it or 0 if the index is invalid or the corresponding node is free. The function supports negative indices as it uses +:ocv:cfunc:`GetSeqElem` +to locate the node. + +GraphAddEdge +------------ +Adds an edge to a graph. + +.. ocv:cfunction:: int cvGraphAddEdge( CvGraph* graph, int start_idx, int end_idx, const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL ) + + :param graph: Graph + + :param start_idx: Index of the starting vertex of the edge + + :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + + :param edge: Optional input parameter, initialization data for the edge + + :param inserted_edge: Optional output parameter to contain the address of the inserted edge + +The function connects two specified vertices. The function returns 1 if the edge has been added successfully, 0 if the edge connecting the two vertices exists already and -1 if either of the vertices was not found, the starting and the ending vertex are the same, or there is some other critical situation. In the latter case (i.e., when the result is negative), the function also reports an error by default. + +GraphAddEdgeByPtr +----------------- +Adds an edge to a graph by using its pointer. + +.. ocv:cfunction:: int cvGraphAddEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx, const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL ) + + :param graph: Graph + + :param start_vtx: Pointer to the starting vertex of the edge + + :param end_vtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + + :param edge: Optional input parameter, initialization data for the edge + + :param inserted_edge: Optional output parameter to contain the address of the inserted edge within the edge set + +The function connects two specified vertices. The +function returns 1 if the edge has been added successfully, 0 if the +edge connecting the two vertices exists already, and -1 if either of the +vertices was not found, the starting and the ending vertex are the same +or there is some other critical situation. In the latter case (i.e., when +the result is negative), the function also reports an error by default. + +GraphAddVtx +----------- +Adds a vertex to a graph. + +.. ocv:cfunction:: int cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx=NULL, CvGraphVtx** inserted_vtx=NULL ) + + :param graph: Graph + + :param vtx: Optional input argument used to initialize the added vertex (only user-defined fields beyond ``sizeof(CvGraphVtx)`` are copied) + + :param inserted_vertex: Optional output argument. If not ``NULL`` , the address of the new vertex is written here. + +The function adds a vertex to the graph and returns the vertex index. + +GraphEdgeIdx +------------ +Returns the index of a graph edge. + +.. ocv:cfunction:: int cvGraphEdgeIdx( CvGraph* graph, CvGraphEdge* edge ) + + :param graph: Graph + + :param edge: Pointer to the graph edge + +The function returns the index of a graph edge. + +GraphRemoveEdge +--------------- +Removes an edge from a graph. + +.. ocv:cfunction:: void cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx ) + + :param graph: Graph + + :param start_idx: Index of the starting vertex of the edge + + :param end_idx: Index of the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + +The function removes the edge connecting two specified vertices. If the vertices are not connected [in that order], the function does nothing. + +GraphRemoveEdgeByPtr +-------------------- +Removes an edge from a graph by using its pointer. + +.. ocv:cfunction:: void cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx ) + + :param graph: Graph + + :param start_vtx: Pointer to the starting vertex of the edge + + :param end_vtx: Pointer to the ending vertex of the edge. For an unoriented graph, the order of the vertex parameters does not matter. + +The function removes the edge connecting two specified vertices. If the vertices are not connected [in that order], the function does nothing. + +GraphRemoveVtx +-------------- +Removes a vertex from a graph. + +.. ocv:cfunction:: int cvGraphRemoveVtx( CvGraph* graph, int index ) + + :param graph: Graph + + :param vtx_idx: Index of the removed vertex + +The function removes a vertex from a graph +together with all the edges incident to it. The function reports an error +if the input vertex does not belong to the graph. The return value is the +number of edges deleted, or -1 if the vertex does not belong to the graph. + +GraphRemoveVtxByPtr +------------------- +Removes a vertex from a graph by using its pointer. + +.. ocv:cfunction:: int cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx ) + + :param graph: Graph + + :param vtx: Pointer to the removed vertex + +The function removes a vertex from the graph by using its pointer together with all the edges incident to it. The function reports an error if the vertex does not belong to the graph. The return value is the number of edges deleted, or -1 if the vertex does not belong to the graph. + +GraphVtxDegree +-------------- +Counts the number of edges indicent to the vertex. + +.. ocv:cfunction:: int cvGraphVtxDegree( const CvGraph* graph, int vtxIdx ) + + :param graph: Graph + + :param vtxIdx: Index of the graph vertex + +The function returns the number of edges incident to the specified vertex, both incoming and outgoing. To count the edges, the following code is used: + +:: + + CvGraphEdge* edge = vertex->first; int count = 0; + while( edge ) + { + edge = CV_NEXT_GRAPH_EDGE( edge, vertex ); + count++; + } + +.. + +The macro +``CV_NEXT_GRAPH_EDGE( edge, vertex )`` +returns the edge incident to +``vertex`` +that follows after +``edge`` +. + +GraphVtxDegreeByPtr +------------------- +Finds an edge in a graph. + +.. ocv:cfunction:: int cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx ) + + :param graph: Graph + + :param vtx: Pointer to the graph vertex + +The function returns the number of edges incident to the specified vertex, both incoming and outcoming. + +GraphVtxIdx +----------- +Returns the index of a graph vertex. + +.. ocv:cfunction:: int cvGraphVtxIdx( CvGraph* graph, CvGraphVtx* vtx ) + + :param graph: Graph + + :param vtx: Pointer to the graph vertex + +The function returns the index of a graph vertex. + +InitTreeNodeIterator +-------------------- +Initializes the tree node iterator. + +.. ocv:cfunction:: void cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator, const void* first, int max_level ) + + :param tree_iterator: Tree iterator initialized by the function + + :param first: The initial node to start traversing from + + :param max_level: The maximal level of the tree ( ``first`` node assumed to be at the first level) to traverse up to. For example, 1 means that only nodes at the same level as ``first`` should be visited, 2 means that the nodes on the same level as ``first`` and their direct children should be visited, and so forth. + +The function initializes the tree iterator. The tree is traversed in depth-first order. + +InsertNodeIntoTree +------------------ +Adds a new node to a tree. + +.. ocv:cfunction:: void cvInsertNodeIntoTree( void* node, void* parent, void* frame ) + + :param node: The inserted node + + :param parent: The parent node that is already in the tree + + :param frame: The top level node. If ``parent`` and ``frame`` are the same, the ``v_prev`` field of ``node`` is set to NULL rather than ``parent`` . + +The function adds another node into tree. The function does not allocate any memory, it can only modify links of the tree nodes. + +MakeSeqHeaderForArray +--------------------- +Constructs a sequence header for an array. + +.. ocv:cfunction:: CvSeq* cvMakeSeqHeaderForArray( int seq_type, int header_size, int elem_size, void* elements, int total, CvSeq* seq, CvSeqBlock* block ) + + :param seq_type: Type of the created sequence + + :param header_size: Size of the header of the sequence. Parameter sequence must point to the structure of that size or greater + + :param elem_size: Size of the sequence elements + + :param elements: Elements that will form a sequence + + :param total: Total number of elements in the sequence. The number of array elements must be equal to the value of this parameter. + + :param seq: Pointer to the local variable that is used as the sequence header + + :param block: Pointer to the local variable that is the header of the single sequence block + +The function initializes a sequence +header for an array. The sequence header as well as the sequence block are +allocated by the user (for example, on stack). No data is copied by the +function. The resultant sequence will consists of a single block and +have NULL storage pointer; thus, it is possible to read its elements, +but the attempts to add elements to the sequence will raise an error in +most cases. + +MemStorageAlloc +--------------- +Allocates a memory buffer in a storage block. + +.. ocv:cfunction:: void* cvMemStorageAlloc( CvMemStorage* storage, size_t size ) + + :param storage: Memory storage + + :param size: Buffer size + +The function allocates a memory buffer in +a storage block. The buffer size must not exceed the storage block size, +otherwise a runtime error is raised. The buffer address is aligned by +``CV_STRUCT_ALIGN=sizeof(double)`` +(for the moment) bytes. + +MemStorageAllocString +--------------------- +Allocates a text string in a storage block. + +.. ocv:cfunction:: CvString cvMemStorageAllocString(CvMemStorage* storage, const char* ptr, int len=-1) + +:: + + typedef struct CvString + { + int len; + char* ptr; + } + CvString; + +.. + + :param storage: Memory storage + + :param ptr: The string + + :param len: Length of the string (not counting the ending ``NUL`` ) . If the parameter is negative, the function computes the length. + +The function creates copy of the string +in memory storage. It returns the structure that contains user-passed +or computed length of the string and pointer to the copied string. + +NextGraphItem +------------- +Executes one or more steps of the graph traversal procedure. + +.. ocv:cfunction:: int cvNextGraphItem( CvGraphScanner* scanner ) + + :param scanner: Graph traversal state. It is updated by this function. + +The function traverses through the graph +until an event of interest to the user (that is, an event, specified +in the +``mask`` +in the +:ocv:cfunc:`CreateGraphScanner` +call) is met or the +traversal is completed. In the first case, it returns one of the events +listed in the description of the +``mask`` +parameter above and with +the next call it resumes the traversal. In the latter case, it returns +``CV_GRAPH_OVER`` +(-1). When the event is +``CV_GRAPH_VERTEX`` +, +``CV_GRAPH_BACKTRACKING`` +, or +``CV_GRAPH_NEW_TREE`` +, +the currently observed vertex is stored in +``scanner-:math:`>`vtx`` +. And if the +event is edge-related, the edge itself is stored at +``scanner-:math:`>`edge`` +, +the previously visited vertex - at +``scanner-:math:`>`vtx`` +and the other ending +vertex of the edge - at +``scanner-:math:`>`dst`` +. + +NextTreeNode +------------ +Returns the currently observed node and moves the iterator toward the next node. + +.. ocv:cfunction:: void* cvNextTreeNode( CvTreeNodeIterator* tree_iterator ) + + :param tree_iterator: Tree iterator initialized by the function + +The function returns the currently observed node and then updates the +iterator - moving it toward the next node. In other words, the function +behavior is similar to the +``*p++`` +expression on a typical C +pointer or C++ collection iterator. The function returns NULL if there +are no more nodes. + +PrevTreeNode +------------ +Returns the currently observed node and moves the iterator toward the previous node. + +.. ocv:cfunction:: void* cvPrevTreeNode( CvTreeNodeIterator* tree_iterator ) + + :param tree_iterator: Tree iterator initialized by the function + +The function returns the currently observed node and then updates +the iterator - moving it toward the previous node. In other words, +the function behavior is similar to the +``*p--`` +expression on a +typical C pointer or C++ collection iterator. The function returns NULL +if there are no more nodes. + +ReleaseGraphScanner +------------------- +Completes the graph traversal procedure. + +.. ocv:cfunction:: void cvReleaseGraphScanner( CvGraphScanner** scanner ) + + :param scanner: Double pointer to graph traverser + +The function completes the graph traversal procedure and releases the traverser state. + +ReleaseMemStorage +----------------- +Releases memory storage. + +.. ocv:cfunction:: void cvReleaseMemStorage( CvMemStorage** storage ) + + :param storage: Pointer to the released storage + +The function deallocates all storage memory +blocks or returns them to the parent, if any. Then it deallocates the +storage header and clears the pointer to the storage. All child storage +associated with a given parent storage block must be released before the +parent storage block is released. + +RestoreMemStoragePos +-------------------- +Restores memory storage position. + +.. ocv:cfunction:: void cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos) + + :param storage: Memory storage + + :param pos: New storage top position + +The function restores the position of the storage top from the parameter +``pos`` +. This function and the function +``cvClearMemStorage`` +are the only methods to release memory occupied in memory blocks. Note again that there is no way to free memory in the middle of an occupied portion of a storage block. + +SaveMemStoragePos +----------------- +Saves memory storage position. + +.. ocv:cfunction:: void cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos) + + :param storage: Memory storage + + :param pos: The output position of the storage top + +The function saves the current position +of the storage top to the parameter +``pos`` +. The function +``cvRestoreMemStoragePos`` +can further retrieve this position. + +SeqElemIdx +---------- +Returns the index of a specific sequence element. + +.. ocv:cfunction:: int cvSeqElemIdx( const CvSeq* seq, const void* element, CvSeqBlock** block=NULL ) + + :param seq: Sequence + + :param element: Pointer to the element within the sequence + + :param block: Optional argument. If the pointer is not ``NULL`` , the address of the sequence block that contains the element is stored in this location. + +The function returns the index of a sequence element or a negative number if the element is not found. + +SeqInsert +--------- +Inserts an element in the middle of a sequence. + +.. ocv:cfunction:: char* cvSeqInsert( CvSeq* seq, int beforeIndex, void* element=NULL ) + + :param seq: Sequence + + :param beforeIndex: Index before which the element is inserted. Inserting before 0 (the minimal allowed value of the parameter) is equal to :ocv:cfunc:`SeqPushFront` and inserting before ``seq->total`` (the maximal allowed value of the parameter) is equal to :ocv:cfunc:`SeqPush` . + + :param element: Inserted element + +The function shifts the sequence elements from the inserted position to the nearest end of the sequence and copies the +``element`` +content there if the pointer is not NULL. The function returns a pointer to the inserted element. + +SeqInsertSlice +-------------- +Inserts an array in the middle of a sequence. + +.. ocv:cfunction:: void cvSeqInsertSlice( CvSeq* seq, int beforeIndex, const CvArr* fromArr ) + + :param seq: Sequence + + :param beforeIndex: Index before which the array is inserted + + :param fromArr: The array to take elements from + +The function inserts all +``fromArr`` +array elements at the specified position of the sequence. The array +``fromArr`` +can be a matrix or another sequence. + +SeqInvert +--------- +Reverses the order of sequence elements. + +.. ocv:cfunction:: void cvSeqInvert( CvSeq* seq ) + + :param seq: Sequence + +The function reverses the sequence in-place - the first element becomes the last one, the last element becomes the first one and so forth. + +SeqPop +------ +Removes an element from the end of a sequence. + +.. ocv:cfunction:: void cvSeqPop( CvSeq* seq, void* element=NULL ) + + :param seq: Sequence + + :param element: Optional parameter . If the pointer is not zero, the function copies the removed element to this location. + +The function removes an element from a sequence. The function reports an error if the sequence is already empty. The function has O(1) complexity. + +SeqPopFront +----------- +Removes an element from the beginning of a sequence. + +.. ocv:cfunction:: void cvSeqPopFront( CvSeq* seq, void* element=NULL ) + + :param seq: Sequence + + :param element: Optional parameter. If the pointer is not zero, the function copies the removed element to this location. + +The function removes an element from the beginning of a sequence. The function reports an error if the sequence is already empty. The function has O(1) complexity. + +SeqPopMulti +----------- +Removes several elements from either end of a sequence. + +.. ocv:cfunction:: void cvSeqPopMulti( CvSeq* seq, void* elements, int count, int in_front=0 ) + + :param seq: Sequence + + :param elements: Removed elements + + :param count: Number of elements to pop + + :param in_front: The flags specifying which end of the modified sequence. + + * **CV_BACK** the elements are added to the end of the sequence + + * **CV_FRONT** the elements are added to the beginning of the sequence + +The function removes several elements from either end of the sequence. If the number of the elements to be removed exceeds the total number of elements in the sequence, the function removes as many elements as possible. + +SeqPush +------- +Adds an element to the end of a sequence. + +.. ocv:cfunction:: char* cvSeqPush( CvSeq* seq, void* element=NULL ) + + :param seq: Sequence + + :param element: Added element + +The function adds an element to the end of a sequence and returns a pointer to the allocated element. If the input +``element`` +is NULL, the function simply allocates a space for one more element. + +The following code demonstrates how to create a new sequence using this function: + +:: + + CvMemStorage* storage = cvCreateMemStorage(0); + CvSeq* seq = cvCreateSeq( CV_32SC1, /* sequence of integer elements */ + sizeof(CvSeq), /* header size - no extra fields */ + sizeof(int), /* element size */ + storage /* the container storage */ ); + int i; + for( i = 0; i < 100; i++ ) + { + int* added = (int*)cvSeqPush( seq, &i ); + printf( " + } + + ... + /* release memory storage in the end */ + cvReleaseMemStorage( &storage ); + +.. + +The function has O(1) complexity, but there is a faster method for writing large sequences (see +:ocv:cfunc:`StartWriteSeq` +and related functions). + +SeqPushFront +------------ +Adds an element to the beginning of a sequence. + +.. ocv:cfunction:: char* cvSeqPushFront( CvSeq* seq, void* element=NULL ) + + :param seq: Sequence + + :param element: Added element + +The function is similar to +:ocv:cfunc:`SeqPush` +but it adds the new element to the beginning of the sequence. The function has O(1) complexity. + +SeqPushMulti +------------ +Pushes several elements to either end of a sequence. + +.. ocv:cfunction:: void cvSeqPushMulti( CvSeq* seq, void* elements, int count, int in_front=0 ) + + :param seq: Sequence + + :param elements: Added elements + + :param count: Number of elements to push + + :param in_front: The flags specifying which end of the modified sequence. + + * **CV_BACK** the elements are added to the end of the sequence + + * **CV_FRONT** the elements are added to the beginning of the sequence + +The function adds several elements to either +end of a sequence. The elements are added to the sequence in the same +order as they are arranged in the input array but they can fall into +different sequence blocks. + +SeqRemove +--------- +Removes an element from the middle of a sequence. + +.. ocv:cfunction:: void cvSeqRemove( CvSeq* seq, int index ) + + :param seq: Sequence + + :param index: Index of removed element + +The function removes elements with the given +index. If the index is out of range the function reports an error. An +attempt to remove an element from an empty sequence is a special +case of this situation. The function removes an element by shifting +the sequence elements between the nearest end of the sequence and the +``index`` +-th position, not counting the latter. + +SeqRemoveSlice +-------------- +Removes a sequence slice. + +.. ocv:cfunction:: void cvSeqRemoveSlice( CvSeq* seq, CvSlice slice ) + + :param seq: Sequence + + :param slice: The part of the sequence to remove + +The function removes a slice from the sequence. + +SeqSearch +--------- +Searches for an element in a sequence. + +.. ocv:cfunction:: char* cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func, int is_sorted, int* elem_idx, void* userdata=NULL ) + + :param seq: The sequence + + :param elem: The element to look for + + :param func: The comparison function that returns negative, zero or positive value depending on the relationships among the elements (see also :ocv:cfunc:`SeqSort` ) + + :param is_sorted: Whether the sequence is sorted or not + + :param elem_idx: Output parameter; index of the found element + + :param userdata: The user parameter passed to the compasion function; helps to avoid global variables in some cases + +:: + + /* a < b ? -1 : a > b ? 1 : 0 */ + typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); + +.. + +The function searches for the element in the sequence. If +the sequence is sorted, a binary O(log(N)) search is used; otherwise, a +simple linear search is used. If the element is not found, the function +returns a NULL pointer and the index is set to the number of sequence +elements if a linear search is used, or to the smallest index +``i, seq(i)>elem`` +. + +SeqSlice +-------- +Makes a separate header for a sequence slice. + +.. ocv:cfunction:: CvSeq* cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage=NULL, int copy_data=0 ) + + :param seq: Sequence + + :param slice: The part of the sequence to be extracted + + :param storage: The destination storage block to hold the new sequence header and the copied data, if any. If it is NULL, the function uses the storage block containing the input sequence. + + :param copy_data: The flag that indicates whether to copy the elements of the extracted slice ( ``copy_data!=0`` ) or not ( ``copy_data=0`` ) + +The function creates a sequence that represents the specified slice of the input sequence. The new sequence either shares the elements with the original sequence or has its own copy of the elements. So if one needs to process a part of sequence but the processing function does not have a slice parameter, the required sub-sequence may be extracted using this function. + +SeqSort +------- +Sorts sequence element using the specified comparison function. + +.. ocv:cfunction:: void cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata=NULL ) + +:: + + /* a < b ? -1 : a > b ? 1 : 0 */ + typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); + +.. + + :param seq: The sequence to sort + + :param func: The comparison function that returns a negative, zero, or positive value depending on the relationships among the elements (see the above declaration and the example below) - a similar function is used by ``qsort`` from C runline except that in the latter, ``userdata`` is not used + + :param userdata: The user parameter passed to the compasion function; helps to avoid global variables in some cases + +The function sorts the sequence in-place using the specified criteria. Below is an example of using this function: + +:: + + /* Sort 2d points in top-to-bottom left-to-right order */ + static int cmp_func( const void* _a, const void* _b, void* userdata ) + { + CvPoint* a = (CvPoint*)_a; + CvPoint* b = (CvPoint*)_b; + int y_diff = a->y - b->y; + int x_diff = a->x - b->x; + return y_diff ? y_diff : x_diff; + } + + ... + + CvMemStorage* storage = cvCreateMemStorage(0); + CvSeq* seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage ); + int i; + + for( i = 0; i < 10; i++ ) + { + CvPoint pt; + pt.x = rand() + pt.y = rand() + cvSeqPush( seq, &pt ); + } + + cvSeqSort( seq, cmp_func, 0 /* userdata is not used here */ ); + + /* print out the sorted sequence */ + for( i = 0; i < seq->total; i++ ) + { + CvPoint* pt = (CvPoint*)cvSeqElem( seq, i ); + printf( "( + } + + cvReleaseMemStorage( &storage ); + +.. + +SetAdd +------ +Occupies a node in the set. + +.. ocv:cfunction:: int cvSetAdd( CvSet* setHeader, CvSetElem* elem=NULL, CvSetElem** inserted_elem=NULL ) + + :param setHeader: Set + + :param elem: Optional input argument, an inserted element. If not NULL, the function copies the data to the allocated node (the MSB of the first integer field is cleared after copying). + + :param inserted_elem: Optional output argument; the pointer to the allocated cell + +The function allocates a new node, optionally copies +input element data to it, and returns the pointer and the index to the +node. The index value is taken from the lower bits of the +``flags`` +field of the node. The function has O(1) complexity; however, there exists +a faster function for allocating set nodes (see +:ocv:cfunc:`SetNew` +). + +SetNew +------ +Adds an element to a set (fast variant). + +.. ocv:cfunction:: CvSetElem* cvSetNew( CvSet* setHeader ) + + :param setHeader: Set + +The function is an inline lightweight variant of +:ocv:cfunc:`SetAdd` +. It occupies a new node and returns a pointer to it rather than an index. + +SetRemove +--------- +Removes an element from a set. + +.. ocv:cfunction:: void cvSetRemove( CvSet* setHeader, int index ) + + :param setHeader: Set + + :param index: Index of the removed element + +The function removes an element with a specified +index from the set. If the node at the specified location is not occupied, +the function does nothing. The function has O(1) complexity; however, +:ocv:cfunc:`SetRemoveByPtr` +provides a quicker way to remove a set element +if it is located already. + +SetRemoveByPtr +-------------- +Removes a set element based on its pointer. + +.. ocv:cfunction:: void cvSetRemoveByPtr( CvSet* setHeader, void* elem ) + + :param setHeader: Set + + :param elem: Removed element + +The function is an inline lightweight variant of +:ocv:cfunc:`SetRemove` +that requires an element pointer. The function does not check whether the node is occupied or not - the user should take care of that. + +SetSeqBlockSize +--------------- +Sets up sequence block size. + +.. ocv:cfunction:: void cvSetSeqBlockSize( CvSeq* seq, int deltaElems ) + + :param seq: Sequence + + :param deltaElems: Desirable sequence block size for elements + +The function affects memory allocation +granularity. When the free space in the sequence buffers has run out, +the function allocates the space for +``deltaElems`` +sequence +elements. If this block immediately follows the one previously allocated, +the two blocks are concatenated; otherwise, a new sequence block is +created. Therefore, the bigger the parameter is, the lower the possible +sequence fragmentation, but the more space in the storage block is wasted. When +the sequence is created, the parameter +``deltaElems`` +is set to +the default value of about 1K. The function can be called any time after +the sequence is created and affects future allocations. The function +can modify the passed value of the parameter to meet memory storage +constraints. + +SetSeqReaderPos +--------------- +Moves the reader to the specified position. + +.. ocv:cfunction:: void cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative=0 ) + + :param reader: Reader state + + :param index: The destination position. If the positioning mode is used (see the next parameter), the actual position will be ``index`` mod ``reader->seq->total`` . + + :param is_relative: If it is not zero, then ``index`` is a relative to the current position + +The function moves the read position to an absolute position or relative to the current position. + +StartAppendToSeq +---------------- +Initializes the process of writing data to a sequence. + +.. ocv:cfunction:: void cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer ) + + :param seq: Pointer to the sequence + + :param writer: Writer state; initialized by the function + +The function initializes the process of +writing data to a sequence. Written elements are added to the end of the +sequence by using the +``CV_WRITE_SEQ_ELEM( written_elem, writer )`` +macro. Note +that during the writing process, other operations on the sequence may +yield an incorrect result or even corrupt the sequence (see description of +:ocv:cfunc:`FlushSeqWriter` +, which helps to avoid some of these problems). + +StartReadSeq +------------ +Initializes the process of sequential reading from a sequence. + +.. ocv:cfunction:: void cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, int reverse=0 ) + + :param seq: Sequence + + :param reader: Reader state; initialized by the function + + :param reverse: Determines the direction of the sequence traversal. If ``reverse`` is 0, the reader is positioned at the first sequence element; otherwise it is positioned at the last element. + +The function initializes the reader state. After +that, all the sequence elements from the first one down to the last one +can be read by subsequent calls of the macro +``CV_READ_SEQ_ELEM( read_elem, reader )`` +in the case of forward reading and by using +``CV_REV_READ_SEQ_ELEM( read_elem, reader )`` +in the case of reverse +reading. Both macros put the sequence element to +``read_elem`` +and +move the reading pointer toward the next element. A circular structure +of sequence blocks is used for the reading process, that is, after the +last element has been read by the macro +``CV_READ_SEQ_ELEM`` +, the +first element is read when the macro is called again. The same applies to +``CV_REV_READ_SEQ_ELEM`` +. There is no function to finish the reading +process, since it neither changes the sequence nor creates any temporary +buffers. The reader field +``ptr`` +points to the current element of +the sequence that is to be read next. The code below demonstrates how +to use the sequence writer and reader. + +:: + + CvMemStorage* storage = cvCreateMemStorage(0); + CvSeq* seq = cvCreateSeq( CV_32SC1, sizeof(CvSeq), sizeof(int), storage ); + CvSeqWriter writer; + CvSeqReader reader; + int i; + + cvStartAppendToSeq( seq, &writer ); + for( i = 0; i < 10; i++ ) + { + int val = rand() + CV_WRITE_SEQ_ELEM( val, writer ); + printf(" + } + cvEndWriteSeq( &writer ); + + cvStartReadSeq( seq, &reader, 0 ); + for( i = 0; i < seq->total; i++ ) + { + int val; + #if 1 + CV_READ_SEQ_ELEM( val, reader ); + printf(" + #else /* alternative way, that is prefferable if sequence elements are large, + or their size/type is unknown at compile time */ + printf(" + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + #endif + } + ... + + cvReleaseStorage( &storage ); + +.. + +StartWriteSeq +------------- +Creates a new sequence and initializes a writer for it. + +.. ocv:cfunction:: void cvStartWriteSeq( int seq_flags, int header_size, int elem_size, CvMemStorage* storage, CvSeqWriter* writer ) + + :param seq_flags: Flags of the created sequence. If the sequence is not passed to any function working with a specific type of sequences, the sequence value may be equal to 0; otherwise the appropriate type must be selected from the list of predefined sequence types. + + :param header_size: Size of the sequence header. The parameter value may not be less than ``sizeof(CvSeq)`` . If a certain type or extension is specified, it must fit within the base type header. + + :param elem_size: Size of the sequence elements in bytes; must be consistent with the sequence type. For example, if a sequence of points is created (element type ``CV_SEQ_ELTYPE_POINT`` ), then the parameter ``elem_size`` must be equal to ``sizeof(CvPoint)`` . + + :param storage: Sequence location + + :param writer: Writer state; initialized by the function + +The function is a combination of +:ocv:cfunc:`CreateSeq` +and +:ocv:cfunc:`StartAppendToSeq` +. The pointer to the +created sequence is stored at +``writer->seq`` +and is also returned by the +:ocv:cfunc:`EndWriteSeq` +function that should be called at the end. + +TreeToNodeSeq +------------- +Gathers all node pointers to a single sequence. + +.. ocv:cfunction:: CvSeq* cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage ) + + :param first: The initial tree node + + :param header_size: Header size of the created sequence (sizeof(CvSeq) is the most frequently used value) + + :param storage: Container for the sequence + +The function puts pointers of all nodes reacheable from ``first`` into a single sequence. The pointers are written sequentially in the depth-first order. + diff --git a/modules/core/doc/old_basic_structures.rst b/modules/core/doc/old_basic_structures.rst new file mode 100644 index 0000000000..dbc5068bc6 --- /dev/null +++ b/modules/core/doc/old_basic_structures.rst @@ -0,0 +1,1747 @@ +Basic C Structures and Operations +================================= + +.. highlight:: c + +The section describes the main data structures, used by the OpenCV 1.x API, and the basic functions to create and process the data structures. + +CvPoint +------- + +.. ocv:struct:: CvPoint + +2D point with integer coordinates (usually zero-based). + + .. ocv:member:: int x + + x-coordinate + + .. ocv:member:: int y + + y-coordinate + +.. ocv:cfunction:: CvPoint cvPoint( int x, int y ) + + constructs ``CvPoint`` structure. + +.. ocv:cfunction:: CvPoint cvPointFrom32f( CvPoint32f pt ); + + converts ``CvPoint2D32f`` to ``CvPoint``. + +.. seealso:: :ocv:class:`Point\_` + +CvPoint2D32f +------------ + +.. ocv:struct:: CvPoint2D32f + +2D point with floating-point coordinates. + + .. ocv:member:: float x + + x-coordinate + + .. ocv:member:: float y + + y-coordinate + +.. ocv:cfunction:: CvPoint2D32f cvPoint2D32f( float x, float y ) + + constructs ``CvPoint2D32f`` structure. + +.. ocv:cfunction:: CvPoint2D32f cvPointTo32f( CvPoint pt ) + + converts ``CvPoint`` to ``CvPoint2D32f``. + +.. seealso:: :ocv:class:`Point\_` + +CvPoint3D32f +------------ + +.. ocv:struct:: CvPoint3D32f + +3D point with floating-point coordinates + + .. ocv:member:: float x + + x-coordinate + + .. ocv:member:: float y + + y-coordinate + + .. ocv:member:: float z + + z-coordinate + +.. ocv:cfunction:: CvPoint3D32f cvPoint3D32f( float x, float y, float z ) + + constructs ``CvPoint3D32f`` structure. + +.. seealso:: :ocv:class:`Point3\_` + +CvPoint2D64f +------------ + +.. ocv:struct:: CvPoint2D64f + +2D point with double-precision floating-point coordinates. + + .. ocv:member:: double x + + x-coordinate + + .. ocv:member:: double y + + y-coordinate + +.. ocv:cfunction:: CvPoint2D64f cvPoint2D64f( double x, double y ) + + constructs ``CvPoint2D64f`` structure. + +.. seealso:: :ocv:class:`Point\_` + +CvPoint3D64f +------------ + +.. ocv:struct:: CvPoint3D64f + +3D point with double-precision floating-point coordinates. + + .. ocv:member:: double x + + x-coordinate + + .. ocv:member:: double y + + y-coordinate + + .. ocv:member:: double z + +.. ocv:cfunction:: CvPoint3D64f cvPoint3D64f( double x, double y, double z ) + + constructs ``CvPoint3D64f`` structure. + +.. seealso:: :ocv:class:`Point3\_` + +CvSize +------ + +.. ocv:struct:: CvSize + +Size of a rectangle or an image. + + .. ocv:member:: int width + + Width of the rectangle + + .. ocv:member:: int height + + Height of the rectangle + +.. ocv:cfunction:: CvSize cvSize( int width, int height ) + + constructs ``CvSize`` structure. + +.. seealso:: :ocv:class:`Size\_` + +CvSize2D32f +----------- + +.. ocv:struct:: CvSize2D32f + +Sub-pixel accurate size of a rectangle. + + .. ocv:member:: float width + + Width of the rectangle + + .. ocv:member:: float height + + Height of the rectangle + +.. ocv:cfunction:: CvSize2D32f cvSize2D23f( float width, float height ) + + constructs ``CvSize2D32f`` structure. + +.. seealso:: :ocv:class:`Size\_` + +CvRect +------ + +.. ocv:struct:: CvRect + +Stores coordinates of a rectangle. + + .. ocv:member:: int x + + x-coordinate of the top-left corner + + .. ocv:member:: int y + + y-coordinate of the top-left corner (sometimes bottom-left corner) + + .. ocv:member:: int width + + Width of the rectangle + + .. ocv:member:: int height + + Height of the rectangle + +.. ocv:cfunction:: CvRect cvRect( int x, int y, int width, int height ) + + constructs ``CvRect`` structure. + +.. seealso:: :ocv:class:`Rect\_` + +CvScalar +-------- + +.. ocv:struct:: CvScalar + +A container for 1-,2-,3- or 4-tuples of doubles. + + .. ocv:member:: double[4] val + +.. ocv::cfunction:: CvScalar cvScalar( double val0, double val1=0, double val2=0, double val3=0 ) + + initializes val[0] with val0, val[1] with val1, val[2] with val2 and val[3] with val3. + +.. ocv::cfunction:: CvScalar cvScalarAll( double val0123 ) + + initializes all of val[0]...val[3] with val0123 + +.. ocv::cfunction:: CvScalar cvRealScalar( double val0 ) + + initializes val[0] with val0, val[1], val[2] and val[3] with 0. + +.. seealso:: :ocv:class:`Scalar\_` + +CvTermCriteria +-------------- + +.. ocv:struct:: CvTermCriteria + +Termination criteria for iterative algorithms. + + .. ocv:member:: int type + + type of the termination criteria, one of: + + * ``CV_TERMCRIT_ITER`` - stop the algorithm after ``max_iter`` iterations at maximum. + + * ``CV_TERMCRIT_EPS`` - stop the algorithm after the achieved algorithm-dependent accuracy becomes lower than ``epsilon``. + + * ``CV_TERMCRIT_ITER+CV_TERMCRIT_EPS`` - stop the algorithm after ``max_iter`` iterations or when the achieved accuracy is lower than ``epsilon``, whichever comes the earliest. + + .. ocv:member:: int max_iter + + Maximum number of iterations + + .. ocv:member:: double epsilon + + Required accuracy + +.. seealso:: :ocv:class:`TermCriteria` + +CvMat +----- + +.. ocv:struct:: CvMat + +A multi-channel dense matrix. + + .. ocv:member:: int type + + ``CvMat`` signature (``CV_MAT_MAGIC_VAL``) plus type of the elements. Type of the matrix elements can be retrieved using ``CV_MAT_TYPE`` macro: :: + + int type = CV_MAT_TYPE(matrix->type); + + For description of possible matrix elements, see :ocv:class:`Mat`. + + .. ocv:member:: int step + + Full row length in bytes + + .. ocv:member:: int* refcount + + Underlying data reference counter + + .. ocv:member:: union data + + Pointers to the actual matrix data: + + * ptr - pointer to 8-bit unsigned elements + * s - pointer to 16-bit signed elements + * i - pointer to 32-bit signed elements + * fl - pointer to 32-bit floating-point elements + * db - pointer to 64-bit floating-point elements + + .. ocv:member:: int rows + + Number of rows + + .. ocv:member:: int cols + + Number of columns + +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)``. + +``CvMat`` is now obsolete; consider using :ocv:class:`Mat` instead. + +CvMatND +------- + +.. ocv:struct:: CvMatND + +Multi-dimensional dense multi-channel array. + + .. ocv:member:: int type + + A ``CvMatND`` signature (``CV_MATND_MAGIC_VAL``) plus the type of elements. Type of the matrix elements can be retrieved using ``CV_MAT_TYPE`` macro: :: + + int type = CV_MAT_TYPE(ndmatrix->type); + + .. ocv:member:: int dims + + The number of array dimensions + + .. ocv:member:: int* refcount + + Underlying data reference counter + + .. ocv:member:: union data + + Pointers to the actual matrix data + + * ptr - pointer to 8-bit unsigned elements + * s - pointer to 16-bit signed elements + * i - pointer to 32-bit signed elements + * fl - pointer to 32-bit floating-point elements + * db - pointer to 64-bit floating-point elements + + .. ocv:member:: array dim + + Arrays of pairs (array size along the i-th dimension, distance between neighbor elements along i-th dimension): :: + + for(int i = 0; i < ndmatrix->dims; i++) + printf("size[i] = %d, step[i] = %d\n", ndmatrix->dim[i].size, ndmatrix->dim[i].step); + +``CvMatND`` is now obsolete; consider using :ocv:class:`Mat` instead. + +CvSparseMat +----------- + +.. ocv:struct:: CvSparseMat + +Multi-dimensional sparse multi-channel array. + + .. ocv:member:: int type + + A ``CvSparseMat`` signature (CV_SPARSE_MAT_MAGIC_VAL) plus the type of sparse matrix elements. Similarly to ``CvMat`` and ``CvMatND``, use ``CV_MAT_TYPE()`` to retrieve type of the elements. + + .. ocv:member:: int dims + + Number of dimensions + + .. ocv:member:: int* refcount + + Underlying reference counter. Not used. + + .. ocv:member:: CvSet* heap + + A pool of hash table nodes + + .. ocv:member:: void** hashtable + + The hash table. Each entry is a list of nodes. + + .. ocv:member:: int hashsize + + Size of the hash table + + .. ocv:member:: int[] size + + Array of dimension sizes + +IplImage +-------- + +.. ocv:struct:: IplImage + +IPL image header + + .. ocv:member:: int nSize + + ``sizeof(IplImage)`` + + .. ocv:member:: int ID + + Version, always equals 0 + + .. ocv:member:: int nChannels + + Number of channels. Most OpenCV functions support 1-4 channels. + + .. ocv:member:: int alphaChannel + + Ignored by OpenCV + + .. ocv:member:: int depth + + Channel depth in bits + the optional sign bit ( ``IPL_DEPTH_SIGN`` ). The supported depths are: + + * ``IPL_DEPTH_8U`` - unsigned 8-bit integer. Equivalent to ``CV_8U`` in matrix types. + * ``IPL_DEPTH_8S`` - signed 8-bit integer. Equivalent to ``CV_8S`` in matrix types. + * ``IPL_DEPTH_16U`` - unsigned 16-bit integer. Equivalent to ``CV_16U`` in matrix types. + * ``IPL_DEPTH_16S`` - signed 8-bit integer. Equivalent to ``CV_16S`` in matrix types. + * ``IPL_DEPTH_32S`` - signed 32-bit integer. Equivalent to ``CV_32S`` in matrix types. + * ``IPL_DEPTH_32F`` - single-precision floating-point number. Equivalent to ``CV_32F`` in matrix types. + * ``IPL_DEPTH_64F`` - double-precision floating-point number. Equivalent to ``CV_64F`` in matrix types. + + .. ocv:member:: char[] colorModel + + Ignored by OpenCV. + + .. ocv:member:: char[] channelSeq + + Ignored by OpenCV + + .. ocv:member:: int dataOrder + + 0 = ``IPL_DATA_ORDER_PIXEL`` - interleaved color channels, 1 - separate color channels. :ocv:cfunc:`CreateImage` only creates images with interleaved channels. For example, the usual layout of a color image is: :math:`b_{00} g_{00} r_{00} b_{10} g_{10} r_{10} ...` + + .. ocv:member:: int origin + + 0 - top-left origin, 1 - bottom-left origin (Windows bitmap style) + + .. ocv:member:: int align + + Alignment of image rows (4 or 8). OpenCV ignores this and uses widthStep instead. + + .. ocv:member:: int width + + Image width in pixels + + .. ocv:member:: int height + + Image height in pixels + + .. ocv:member:: IplROI* roi + + Region Of Interest (ROI). If not NULL, only this image region will be processed. + + .. ocv:member:: IplImage* maskROI + + Must be NULL in OpenCV + + .. ocv:member:: void* imageId + + Must be NULL in OpenCV + + .. ocv:member:: void* tileInfo + + Must be NULL in OpenCV + + .. ocv:member:: int imageSize + + Image data size in bytes. For interleaved data, this equals :math:`\texttt{image->height} \cdot \texttt{image->widthStep}` + + .. ocv:member:: char* imageData + + A pointer to the aligned image data. Do not assign imageData directly. Use :ocv:cfunc:`SetData`. + + .. ocv:member:: int widthStep + + The size of an aligned image row, in bytes. + + .. ocv:member:: int[] BorderMode + + Border completion mode, ignored by OpenCV + + .. ocv:member:: int[] BorderConst + + Constant border value, ignored by OpenCV + + .. ocv:member:: char* imageDataOrigin + + A pointer to the origin of the image data (not necessarily aligned). This is used for image deallocation. + +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. + +CvArr +----- + +.. ocv:struct:: CvArr + +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``. + +ClearND +------- +Clears a specific array element. + +.. ocv:cfunction:: void cvClearND(CvArr* arr, int* idx) +.. ocv:pyoldfunction:: cv.ClearND(arr, idx)-> None + + :param arr: Input array + :param idx: Array of the element indices + +The function clears (sets to zero) a specific element of a dense array or deletes the element of a sparse array. If the sparse array element does not exists, the function does nothing. + +CloneImage +---------- +Makes a full copy of an image, including the header, data, and ROI. + +.. ocv:cfunction:: IplImage* cvCloneImage(const IplImage* image) +.. ocv:pyoldfunction:: cv.CloneImage(image)-> copy + + :param image: The original image + +CloneMat +-------- +Creates a full matrix copy. + +.. ocv:cfunction:: CvMat* cvCloneMat(const CvMat* mat) +.. ocv:pyoldfunction:: cv.CloneMat(mat)-> copy + + :param mat: Matrix to be copied + +Creates a full copy of a matrix and returns a pointer to the copy. Note that the matrix copy is compacted, that is, it will not have gaps between rows. + +CloneMatND +---------- +Creates full copy of a multi-dimensional array and returns a pointer to the copy. + +.. ocv:cfunction:: CvMatND* cvCloneMatND(const CvMatND* mat) +.. ocv:pyoldfunction:: cv.CloneMatND(mat)-> copy + + :param mat: Input array + +CloneSparseMat +-------------- +Creates full copy of sparse array. + +.. ocv:cfunction:: CvSparseMat* cvCloneSparseMat(const CvSparseMat* mat) + + :param mat: Input array + +The function creates a copy of the input array and returns pointer to the copy. + + +ConvertScale +------------ +Converts one array to another with optional linear transformation. + +.. ocv:cfunction:: void cvConvertScale(const CvArr* src, CvArr* dst, double scale=1, double shift=0) +.. ocv:pyoldfunction:: cv.ConvertScale(src, dst, scale=1.0, shift=0.0)-> None +.. ocv:pyoldfunction:: cv.Convert(src, dst)-> None + +:: + + #define cvCvtScale cvConvertScale + #define cvScale cvConvertScale + #define cvConvert(src, dst ) cvConvertScale((src), (dst), 1, 0 ) + +.. + + :param src: Source array + + :param dst: Destination array + + :param scale: Scale factor + + :param shift: Value added to the scaled source array elements + +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: + +.. math:: + + \texttt{dst} (I) = \texttt{scale} \texttt{src} (I) + ( \texttt{shift} _0, \texttt{shift} _1,...) + + +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. + + +Copy +---- +Copies one array to another. + +.. cfunction:: void cvCopy(const CvArr* src, CvArr* dst, const CvArr* mask=NULL) +.. ocv:pyoldfunction:: cv.Copy(src, dst, mask=None)-> None + + :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 + +The function copies selected elements from an input array to an output array: + +.. math:: + + \texttt{dst} (I)= \texttt{src} (I) \quad \text{if} \quad \texttt{mask} (I) \ne 0. + +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). + + +CreateData +---------- +Allocates array data + +.. ocv:cfunction:: void cvCreateData(CvArr* arr) +.. ocv:pyoldfunction:: cv.CreateData(arr) -> None + + :param arr: Array header + +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. + +CreateImage +----------- +Creates an image header and allocates the image data. + +.. ocv:cfunction:: IplImage* cvCreateImage(CvSize size, int depth, int channels) +.. ocv:pyoldfunction:: cv.CreateImage(size, depth, channels)->image + + :param size: Image width and height + + :param depth: Bit depth of image elements. See :ocv:struct:`IplImage` for valid depths. + + :param channels: Number of channels per pixel. See :ocv:struct:`IplImage` for details. This function only creates images with interleaved channels. + +This function call is equivalent to the following code: :: + + header = cvCreateImageHeader(size, depth, channels); + cvCreateData(header); + +CreateImageHeader +----------------- +Creates an image header but does not allocate the image data. + +.. ocv:cfunction:: IplImage* cvCreateImageHeader(CvSize size, int depth, int channels) +.. ocv:pyoldfunction:: cv.CreateImageHeader(size, depth, channels) -> image + + :param size: Image width and height + + :param depth: Image depth (see :ocv:cfunc:`CreateImage` ) + + :param channels: Number of channels (see :ocv:cfunc:`CreateImage` ) + +CreateMat +--------- +Creates a matrix header and allocates the matrix data. + +.. ocv:cfunction:: CvMat* cvCreateMat( int rows, int cols, int type) +.. ocv:pyoldfunction:: cv.CreateMat(rows, cols, type) -> mat + + :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. + +The function call is equivalent to the following code: :: + + CvMat* mat = cvCreateMatHeader(rows, cols, type); + cvCreateData(mat); + +CreateMatHeader +--------------- +Creates a matrix header but does not allocate the matrix data. + +.. ocv:cfunction:: CvMat* cvCreateMatHeader( int rows, int cols, int type) +.. ocv:pyoldfunction:: cv.CreateMatHeader(rows, cols, type) -> mat + + :param rows: Number of rows in the matrix + + :param cols: Number of columns in the matrix + + :param type: Type of the matrix elements, see :ocv:cfunc:`CreateMat` + +The function allocates a new matrix header and returns a pointer to it. The matrix data can then be allocated using :ocv:cfunc:`CreateData` or set explicitly to user-allocated data via :ocv:func:`SetData`. + +CreateMatND +----------- +Creates the header and allocates the data for a multi-dimensional dense array. + +.. ocv:cfunction:: CvMatND* cvCreateMatND( int dims, const int* sizes, int type) +.. ocv:pyoldfunction:: cv.CreateMatND(dims, type) -> None + + :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 :ocv:cfunc:`CreateMat` . + +This function call is equivalent to the following code: :: + + CvMatND* mat = cvCreateMatNDHeader(dims, sizes, type); + cvCreateData(mat); + +CreateMatNDHeader +----------------- +Creates a new matrix header but does not allocate the matrix data. + +.. ocv:cfunction:: CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type) +.. ocv:pyoldfunction:: cv.CreateMatNDHeader(dims, type) -> None + + :param dims: Number of array dimensions + + :param sizes: Array of dimension sizes + + :param type: Type of array elements, see :ocv:cfunc:`CreateMat` + +The function allocates a header for a multi-dimensional dense array. The array data can further be allocated using :ocv:cfunc:`CreateData` or set explicitly to user-allocated data via :ocv:cfunc:`SetData`. + +CreateSparseMat +--------------- +Creates sparse array. + +.. ocv:cfunction:: CvSparseMat* cvCreateSparseMat(int dims, const int* sizes, int type) + + :param dims: Number of array dimensions. In contrast to the dense matrix, the number of dimensions is practically unlimited (up to :math:`2^{16}` ). + + :param sizes: Array of dimension sizes + + :param type: Type of array elements. The same as for CvMat + +The function allocates a multi-dimensional sparse array. Initially the array contain no elements, that is +:ocv:cfunc:`GetPtrND` and other related functions will return 0 for every index. + + +CrossProduct +------------ +Calculates the cross product of two 3D vectors. + +.. ocv:cfunction:: void cvCrossProduct(const CvArr* src1, const CvArr* src2, CvArr* dst) +.. ocv:pyoldfunction:: cv.CrossProduct(src1, src2, dst)-> None + + :param src1: The first source vector + + :param src2: The second source vector + + :param dst: The destination vector + +The function calculates the cross product of two 3D vectors: + +.. math:: + + \texttt{dst} = \texttt{src1} \times \texttt{src2} + +or: + +.. math:: + + \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} + + +DotProduct +---------- +Calculates the dot product of two arrays in Euclidian metrics. + +.. ocv:cfunction:: double cvDotProduct(const CvArr* src1, const CvArr* src2) +.. ocv:pyoldfunction:: cv.DotProduct(src1, src2)-> double + + :param src1: The first source array + + :param src2: The second source array + +The function calculates and returns the Euclidean dot product of two arrays. + +.. math:: + + src1 \bullet src2 = \sum _I ( \texttt{src1} (I) \texttt{src2} (I)) + +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 :math:`||\texttt{a}||^2`. +The function can process multi-dimensional arrays, row by row, layer by layer, and so on. + + +Get?D +----- + +.. ocv:cfunction:: CvScalar cvGet1D(const CvArr* arr, int idx0) +.. ocv:cfunction:: CvScalar cvGet2D(const CvArr* arr, int idx0, int idx1) +.. ocv:cfunction:: CvScalar cvGet3D(const CvArr* arr, int idx0, int idx1, int idx2) +.. ocv:cfunction:: CvScalar cvGetND(const CvArr* arr, int* idx) + +.. ocv:pyoldfunction:: cv.Get1D(arr, idx) -> scalar +.. ocv:pyoldfunction:: cv.Get2D(arr, idx0, idx1) -> scalar +.. ocv:pyoldfunction:: cv.Get3D(arr, idx0, idx1, idx2) -> scalar +.. ocv:pyoldfunction:: cv.GetND(arr, indices) -> scalar + + Return a specific array element. + + :param arr: Input array + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + +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). + +GetCol(s) +--------- +Returns one of more array columns. + +.. ocv:cfunction:: CvMat* cvGetCol(const CvArr* arr, CvMat* submat, int col) +.. ocv:cfunction:: CvMat* cvGetCols(const CvArr* arr, CvMat* submat, int startCol, int endCol) + +.. ocv:pyoldfunction:: cv.GetCol(arr, col)-> submat +.. ocv:pyoldfunction:: cv.GetCols(arr, startCol, endCol)-> submat + + :param arr: Input array + + :param submat: Pointer to the resulting sub-array header + + :param col: Zero-based index of the selected column + + :param startCol: Zero-based index of the starting column (inclusive) of the span + + :param endCol: Zero-based index of the ending column (exclusive) of the span + +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 :ocv:cfunc:`CloneMat`. ``cvGetCol(arr, submat, col)`` is a shortcut for ``cvGetCols(arr, submat, col, col+1)``. + +GetDiag +------- +Returns one of array diagonals. + +.. ocv:cfunction:: CvMat* cvGetDiag(const CvArr* arr, CvMat* submat, int diag=0) +.. ocv:pyoldfunction:: cv.GetDiag(arr, diag=0)-> submat + + :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. + +The function returns the header, corresponding to a specified diagonal of the input array. + +GetDims +--------- +Return number of array dimensions + +.. ocv:cfunction:: int cvGetDims(const CvArr* arr, int* sizes=NULL) +.. ocv:pyoldfunction:: cv.GetDims(arr)-> list + + :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. + +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: :: + + int sizes[CV_MAX_DIM]; + int i, total = 1; + int dims = cvGetDims(arr, size); + for(i = 0; i < dims; i++ ) + total *= sizes[i]; + +GetDimSize +------------ +Returns array size along the specified dimension. + +.. ocv:cfunction:: int cvGetDimSize(const CvArr* arr, int index) + + :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) + +GetElemType +----------- +Returns type of array elements. + +.. ocv:cfunction:: int cvGetElemType(const CvArr* arr) +.. ocv:pyoldfunction:: cv.GetElemType(arr)-> int + + :param arr: Input array + +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: :: + + IplImage* img = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); + +The code ``cvGetElemType(img)`` will return ``CV_8UC3``. + +GetImage +-------- +Returns image header for arbitrary array. + +.. ocv:cfunction:: IplImage* cvGetImage(const CvArr* arr, IplImage* imageHeader) +.. ocv:pyoldfunction:: cv.GetImage(arr) -> iplimage + + :param arr: Input array + + :param imageHeader: Pointer to ``IplImage`` structure used as a temporary buffer + +The function returns the image header for the input array that can be a matrix (:ocv:struct:`CvMat`) or image (:ocv:struct:`IplImage`). In the case of an image the function simply returns the input pointer. In the case of ``CvMat`` it initializes an ``imageHeader`` structure with the parameters of the input matrix. Note that if we transform ``IplImage`` to ``CvMat`` using :ocv:cfunc:`GetMat` and then transform ``CvMat`` back to IplImage using this function, we will get different headers if the ROI is set in the original image. + +GetImageCOI +----------- +Returns the index of the channel of interest. + +.. ocv:cfunction:: int cvGetImageCOI(const IplImage* image) +.. ocv:pyoldfunction:: cv.GetImageCOI(image)-> channel + + :param image: A pointer to the image header + +Returns the channel of interest of in an IplImage. Returned values correspond to the ``coi`` in +:ocv:cfunc:`SetImageCOI`. + +GetImageROI +----------- +Returns the image ROI. + +.. ocv:cfunction:: CvRect cvGetImageROI(const IplImage* image) +.. ocv:pyoldfunction:: cv.GetImageROI(image)-> CvRect + + :param image: A pointer to the image header + +If there is no ROI set, ``cvRect(0,0,image->width,image->height)`` is returned. + +GetMat +------ +Returns matrix header for arbitrary array. + +.. ocv:cfunction:: CvMat* cvGetMat(const CvArr* arr, CvMat* header, int* coi=NULL, int allowND=0) +.. ocv:pyoldfunction:: cv.GetMat(arr, allowND=0) -> cvmat + + :param arr: Input array + + :param header: Pointer to :ocv:struct:`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. + +The function returns a matrix header for the input array that can be a matrix - :ocv:struct:`CvMat`, an image - :ocv:struct:`IplImage`, or a multi-dimensional dense array - :ocv:struct:`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. + +.. seealso:: :ocv:cfunc:`GetImage`, :ocv:cfunc:`GetMatND`, :ocv:func:`cvarrToMat`. + +.. 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`` strctures with planar data layout, even though OpenCV does not support such images. + +GetNextSparseNode +----------------- +Returns the next sparse matrix element + +.. ocv:cfunction:: CvSparseNode* cvGetNextSparseNode(CvSparseMatIterator* matIterator) + + :param matIterator: Sparse array iterator + +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: :: + + // 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)) + { + /* get pointer to the element indices */ + int* idx = CV_NODE_IDX(array, node); + /* get value of the element (assume that the type is CV_32FC1) */ + 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); + + +GetRawData +---------- +Retrieves low-level information about the array. + +.. ocv:cfunction:: void cvGetRawData(const CvArr* arr, uchar** data, int* step=NULL, CvSize* roiSize=NULL) + + :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 roiSize: Output ROI size + +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 :: + + 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]); + +GetReal?D +--------- +Return a specific element of single-channel 1D, 2D, 3D or nD array. + +.. ocv:cfunction:: double cvGetReal1D(const CvArr* arr, int idx0) +.. ocv:cfunction:: double cvGetReal2D(const CvArr* arr, int idx0, int idx1) +.. ocv:cfunction:: double cvGetReal3D(const CvArr* arr, int idx0, int idx1, int idx2) +.. ocv:cfunction:: double cvGetRealND(const CvArr* arr, int* idx) + +.. ocv:pyoldfunction:: cv.GetReal1D(arr, idx0)->float +.. ocv:pyoldfunction:: cv.GetReal2D(arr, idx0, idx1)->float +.. ocv:pyoldfunction:: cv.GetReal3D(arr, idx0, idx1, idx2)->float +.. ocv:pyoldfunction:: cv.GetRealND(arr, idx)->float + + :param arr: Input array. Must have a single channel. + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + +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). + + +GetRow(s) +--------- +Returns array row or row span. + +.. ocv:cfunction:: CvMat* cvGetRow(const CvArr* arr, CvMat* submat, int row) + +.. ocv:cfunction:: CvMat* cvGetRows(const CvArr* arr, CvMat* submat, int startRow, int endRow, int deltaRow=1) + +.. ocv:pyoldfunction:: cv.GetRow(arr, row)-> submat +.. ocv:pyoldfunction:: cv.GetRows(arr, startRow, endRow, deltaRow=1)-> submat + + :param arr: Input array + + :param submat: Pointer to the resulting sub-array header + + :param row: Zero-based index of the selected row + + :param startRow: Zero-based index of the starting row (inclusive) of the span + + :param endRow: Zero-based index of the ending row (exclusive) of the span + + :param deltaRow: Index step in the row span. That is, the function extracts every ``deltaRow`` -th row from ``startRow`` and up to (but not including) ``endRow`` . + +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)``. + + +GetSize +------- +Returns size of matrix or image ROI. + +.. ocv:cfunction:: CvSize cvGetSize(const CvArr* arr) +.. ocv:pyoldfunction:: cv.GetSize(arr)-> (width, height) + + :param arr: array header + +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. + +GetSubRect +---------- +Returns matrix header corresponding to the rectangular sub-array of input image or matrix. + +.. ocv:cfunction:: CvMat* cvGetSubRect(const CvArr* arr, CvMat* submat, CvRect rect) +.. ocv:pyoldfunction:: cv.GetSubRect(arr, rect) -> submat + + :param arr: Input array + + :param submat: Pointer to the resultant sub-array header + + :param rect: Zero-based coordinates of the rectangle of interest + +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. + +DecRefData +---------- +Decrements an array data reference counter. + +.. ocv:cfunction:: void cvDecRefData(CvArr* arr) + + :param arr: Pointer to an array header + +The function decrements the data reference counter in a :ocv:struct:`CvMat` or :ocv:struct:`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 :ocv:cfunc:`CreateData` function. The counter will be NULL in other cases such as: external data was assigned to the header using :ocv:cfunc:`SetData`, header is part of a larger matrix or image, or the header was converted from an image or n-dimensional matrix header. + + +IncRefData +---------- +Increments array data reference counter. + +.. ocv:cfunction:: int cvIncRefData(CvArr* arr) + + :param arr: Array header + +The function increments :ocv:struct:`CvMat` or :ocv:struct:`CvMatND` data reference counter and returns the new counter value if the reference counter pointer is not NULL, otherwise it returns zero. + + +InitImageHeader +--------------- +Initializes an image header that was previously allocated. + +.. ocv:cfunction:: IplImage* cvInitImageHeader( IplImage* image, CvSize size, int depth, int channels, int origin=0, int align=4) + + :param image: Image header to initialize + + :param size: Image width and height + + :param depth: Image depth (see :ocv:cfunc:`CreateImage` ) + + :param channels: Number of channels (see :ocv:cfunc:`CreateImage` ) + + :param origin: Top-left ``IPL_ORIGIN_TL`` or bottom-left ``IPL_ORIGIN_BL`` + + :param align: Alignment for image rows, typically 4 or 8 bytes + +The returned ``IplImage*`` points to the initialized header. + + +InitMatHeader +------------- +Initializes a pre-allocated matrix header. + +.. ocv:cfunction:: CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, int type, void* data=NULL, int step=CV_AUTOSTEP) + + :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 :ocv:cfunc:`CreateMat` . + + :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. + +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: :: + + 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) + + +InitMatNDHeader +--------------- +Initializes a pre-allocated multi-dimensional array header. + +.. ocv:cfunction:: CvMatND* cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int type, void* data=NULL) + + :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 :ocv:cfunc:`CreateMat` + + :param data: Optional data pointer assigned to the matrix header + + +InitSparseMatIterator +--------------------- +Initializes sparse array elements iterator. + +.. ocv:cfunction:: CvSparseNode* cvInitSparseMatIterator(const CvSparseMat* mat, CvSparseMatIterator* matIterator) + + :param mat: Input array + + :param matIterator: Initialized iterator + +The function initializes iterator of sparse array elements and returns pointer to the first element, or NULL if the array is empty. + + +Mat +--- +Initializes matrix header (lightweight variant). + +.. ocv:cfunction:: CvMat cvMat( int rows, int cols, int type, void* data=NULL) + + :param rows: Number of rows in the matrix + + :param cols: Number of columns in the matrix + + :param type: Type of the matrix elements - see :ocv:cfunc:`CreateMat` + + :param data: Optional data pointer assigned to the matrix header + +Initializes a matrix header and assigns data to it. The matrix is filled *row*-wise (the first ``cols`` elements of data form the first row of the matrix, etc.) + +This function is a fast inline substitution for :ocv:cfunc:`InitMatHeader`. Namely, it is equivalent to: :: + + CvMat mat; + cvInitMatHeader(&mat, rows, cols, type, data, CV_AUTOSTEP); + + +Ptr?D +----- +Return pointer to a particular array element. + +.. ocv:cfunction:: uchar* cvPtr1D(const CvArr* arr, int idx0, int* type=NULL) + +.. ocv:cfunction:: uchar* cvPtr2D(const CvArr* arr, int idx0, int idx1, int* type=NULL) + +.. ocv:cfunction:: uchar* cvPtr3D(const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL) + +.. ocv:cfunction:: uchar* cvPtrND(const CvArr* arr, int* idx, int* type=NULL, int createNode=1, unsigned* precalcHashval=NULL) + + :param arr: Input array + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + + :param type: Optional output parameter: type of matrix elements + + :param createNode: 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 precalcHashval: 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) + +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 ( +:ocv:cfunc:`Get` +, +:ocv:cfunc:`GetReal` +, +:ocv:cfunc:`Set` +, +:ocv:cfunc:`SetReal` +) raise an error in case if the element index is out of range. + + +ReleaseData +----------- +Releases array data. + +.. ocv:cfunction:: void cvReleaseData(CvArr* arr) + + :param arr: Array header + +The function releases the array data. In the case of +:ocv:struct:`CvMat` +or +:ocv:struct:`CvMatND` +it simply calls cvDecRefData(), that is the function can not deallocate external data. See also the note to +:ocv:cfunc:`CreateData` +. + + +ReleaseImage +------------ +Deallocates the image header and the image data. + +.. ocv:cfunction:: void cvReleaseImage(IplImage** image) + + :param image: Double pointer to the image header + +This call is a shortened form of :: + + if(*image ) + { + cvReleaseData(*image); + cvReleaseImageHeader(image); + } + +.. + +ReleaseImageHeader +------------------ +Deallocates an image header. + +.. ocv:cfunction:: void cvReleaseImageHeader(IplImage** image) + + :param image: Double pointer to the image header + +This call is an analogue of :: + + if(image ) + { + iplDeallocate(*image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI); + *image = 0; + } + +.. + +but it does not use IPL functions by default (see the ``CV_TURN_ON_IPL_COMPATIBILITY`` macro). + + +ReleaseMat +---------- +Deallocates a matrix. + +.. ocv:cfunction:: void cvReleaseMat(CvMat** mat) + + :param mat: Double pointer to the 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. :: + + if(*mat ) + cvDecRefData(*mat); + cvFree((void**)mat); + +.. + +ReleaseMatND +------------ +Deallocates a multi-dimensional array. + +.. ocv:cfunction:: void cvReleaseMatND(CvMatND** mat) + + :param mat: Double pointer to the 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. :: + + if(*mat ) + cvDecRefData(*mat); + cvFree((void**)mat); + +.. + +ReleaseSparseMat +---------------- +Deallocates sparse array. + +.. ocv:cfunction:: void cvReleaseSparseMat(CvSparseMat** mat) + + :param mat: Double pointer to the array + +The function releases the sparse array and clears the array pointer upon exit. + +ResetImageROI +------------- +Resets the image ROI to include the entire image and releases the ROI structure. + +.. ocv:cfunction:: void cvResetImageROI(IplImage* image) +.. ocv:pyoldfunction:: cv.ResetImageROI(image)-> None + + :param image: A pointer to the image header + +This produces a similar result to the following, but in addition it releases the ROI structure. :: + + cvSetImageROI(image, cvRect(0, 0, image->width, image->height )); + cvSetImageCOI(image, 0); + +.. + +Reshape +------- +Changes shape of matrix/image without copying data. + +.. ocv:cfunction:: CvMat* cvReshape(const CvArr* arr, CvMat* header, int newCn, int newRows=0) +.. ocv:pyoldfunction:: cv.Reshape(arr, newCn, newRows=0) -> cvmat + + :param arr: Input array + + :param header: Output header to be filled + + :param newCn: New number of channels. 'newCn = 0' means that the number of channels remains unchanged. + + :param newRows: New number of rows. 'newRows = 0' means that the number of rows remains unchanged unless it needs to be changed according to ``newCn`` value. + +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: :: + + 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); + +.. + +And the next example converts a 3x3 matrix to a single 1x9 vector: + +:: + + CvMat* mat = cvCreateMat(3, 3, CV_32F); + CvMat row_header, *row; + row = cvReshape(mat, &row_header, 0, 1); + +.. + +ReshapeMatND +------------ +Changes the shape of a multi-dimensional array without copying the data. + +.. ocv:cfunction:: CvArr* cvReshapeMatND(const CvArr* arr, int sizeofHeader, CvArr* header, int newCn, int newDims, int* newSizes) +.. ocv:pyoldfunction:: cv.ReshapeMatND(arr, newCn, newDims) -> cvmat + + :param arr: Input array + + :param sizeofHeader: Size of output header to distinguish between IplImage, CvMat and CvMatND output headers + + :param header: Output header to be filled + + :param newCn: New number of channels. ``newCn = 0`` means that the number of channels remains unchanged. + + :param newDims: New number of dimensions. ``newDims = 0`` means that the number of dimensions remains the same. + + :param newSizes: Array of new dimension sizes. Only ``newDims-1`` values are used, because the total number of elements must remain the same. Thus, if ``newDims = 1``, ``newSizes`` array is not used. + +The function is an advanced version of :ocv:cfunc:`Reshape` 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 +:ocv:cfunc:`Reshape` +description rewritten using +:ocv:cfunc:`ReshapeMatND` +: :: + + IplImage* color_img = cvCreateImage(cvSize(320,240), IPL_DEPTH_8U, 3); + IplImage gray_img_hdr, *gray_img; + gray_img = (IplImage*)cvReshapeND(color_img, &gray_img_hdr, 1, 0, 0); + + ... + + /* second example is modified to convert 2x2x2 array to 8x1 vector */ + int size[] = { 2, 2, 2 }; + CvMatND* mat = cvCreateMatND(3, size, CV_32F); + CvMat row_header, *row; + row = (CvMat*)cvReshapeND(mat, &row_header, 0, 1, 0); + +.. + +Set +--- +Sets every element of an array to a given value. + +.. ocv:cfunction:: void cvSet(CvArr* arr, CvScalar value, const CvArr* mask=NULL) +.. ocv:pyoldfunction:: cv.Set(arr, value, mask=None)-> None + + :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 + +The function copies the scalar ``value`` to every selected element of the destination array: + +.. math:: + + \texttt{arr} (I)= \texttt{value} \quad \text{if} \quad \texttt{mask} (I) \ne 0 + +If array ``arr`` is of ``IplImage`` type, then is ROI used, but COI must not be set. + +Set?D +----- +Change the particular array element. + +.. ocv:cfunction:: void cvSet1D(CvArr* arr, int idx0, CvScalar value) + +.. ocv:cfunction:: void cvSet2D(CvArr* arr, int idx0, int idx1, CvScalar value) + +.. ocv:cfunction:: void cvSet3D(CvArr* arr, int idx0, int idx1, int idx2, CvScalar value) + +.. ocv:cfunction:: void cvSetND(CvArr* arr, int* idx, CvScalar value) + +.. ocv:pyoldfunction:: cv.Set1D(arr, idx, value) -> None +.. ocv:pyoldfunction:: cv.Set2D(arr, idx0, idx1, value) -> None +.. ocv:pyoldfunction:: cv.Set3D(arr, idx0, idx1, idx2, value) -> None +.. ocv:pyoldfunction:: cv.SetND(arr, indices, value) -> None + + + :param arr: Input array + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + + :param value: The assigned value + +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. + +SetData +------- +Assigns user data to the array header. + +.. ocv:cfunction:: void cvSetData(CvArr* arr, void* data, int step) +.. ocv:pyoldfunction:: cv.SetData(arr, data, step)-> None + + :param arr: Array header + + :param data: User data + + :param step: Full row length in bytes + +The function assigns user data to the array header. Header should be initialized before using +:ocv:cfunc:`cvCreateMatHeader`, :ocv:cfunc:`cvCreateImageHeader`, :ocv:cfunc:`cvCreateMatNDHeader`, +:ocv:cfunc:`cvInitMatHeader`, :ocv:cfunc:`cvInitImageHeader` or :ocv:cfunc:`cvInitMatNDHeader`. + + + +SetImageCOI +----------- +Sets the channel of interest in an IplImage. + +.. ocv:cfunction:: void cvSetImageCOI( IplImage* image, int coi) +.. ocv:pyoldfunction:: cv.SetImageCOI(image, coi)-> None + + :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. + +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 :ocv:cfunc:`Copy` or :ocv:cfunc:`Split`) the channel to a separate image/matrix, process it and then copy the result back (via :ocv:cfunc:`Copy` or :ocv:cfunc:`Merge`) if needed. + + +SetImageROI +----------- +Sets an image Region Of Interest (ROI) for a given rectangle. + +.. ocv:cfunction:: void cvSetImageROI( IplImage* image, CvRect rect) +.. ocv:pyoldfunction:: cv.SetImageROI(image, rect)-> None + + :param image: A pointer to the image header + + :param rect: The ROI 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. + + +SetReal?D +--------- +Change a specific array element. + +.. ocv:cfunction:: void cvSetReal1D(CvArr* arr, int idx0, double value) + +.. ocv:cfunction:: void cvSetReal2D(CvArr* arr, int idx0, int idx1, double value) + +.. ocv:cfunction:: void cvSetReal3D(CvArr* arr, int idx0, int idx1, int idx2, double value) + +.. ocv:cfunction:: void cvSetRealND(CvArr* arr, int* idx, double value) + +.. ocv:pyoldfunction:: cv.SetReal1D(arr, idx, value) -> None +.. ocv:pyoldfunction:: cv.SetReal2D(arr, idx0, idx1, value) -> None +.. ocv:pyoldfunction:: cv.SetReal3D(arr, idx0, idx1, idx2, value) -> None +.. ocv:pyoldfunction:: cv.SetRealND(arr, indices, value) -> None + + :param arr: Input array + + :param idx0: The first zero-based component of the element index + + :param idx1: The second zero-based component of the element index + + :param idx2: The third zero-based component of the element index + + :param idx: Array of the element indices + + :param value: The assigned value + +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. + +SetZero +------- +Clears the array. + +.. ocv:cfunction:: void cvSetZero(CvArr* arr) +.. ocv:pyoldfunction:: cv.SetZero(arr)-> None + + :param arr: Array to be cleared + +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. + +mGet +---- +Returns the particular element of single-channel floating-point matrix. + +.. ocv:cfunction:: double cvmGet(const CvMat* mat, int row, int col) +.. ocv:pyoldfunction:: cv.mGet(mat, row, col)-> double + + :param mat: Input matrix + + :param row: The zero-based index of row + + :param col: The zero-based index of column + +The function is a fast replacement for :ocv:cfunc:`GetReal2D` 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. + +mSet +---- +Sets a specific element of a single-channel floating-point matrix. + +.. ocv:cfunction:: void cvmSet(CvMat* mat, int row, int col, double value) +.. ocv:pyoldfunction:: cv.mSet(mat, row, col, value)-> None + + :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 + +The function is a fast replacement for :ocv:cfunc:`SetReal2D` 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. + + +SetIPLAllocators +---------------- +Makes OpenCV use IPL functions for allocating IplImage and IplROI structures. + +.. cfunction:: void cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, Cv_iplAllocateImageData allocate_data, Cv_iplDeallocate deallocate, Cv_iplCreateROI create_roi, Cv_iplCloneImage clone_image ) + +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. :: + + ... + CV_TURN_ON_IPL_COMPATIBILITY() + ... + + +RNG +--- +Initializes a random number generator state. + +.. ocv:cfunction:: CvRNG cvRNG(int64 seed=-1) +.. ocv:pyoldfunction:: cv.RNG(seed=-1LL)-> CvRNG + + :param seed: 64-bit value used to initiate a random sequence + +The function initializes a random number generator and returns the state. The pointer to the state can be then passed to the :ocv:cfunc:`RandInt`, :ocv:cfunc:`RandReal` and :ocv:cfunc:`RandArr` functions. In the current implementation a multiply-with-carry generator is used. + +.. sealso:: the C++ class :ocv:class:`RNG` replaced ``CvRNG``. + + +RandArr +------- +Fills an array with random numbers and updates the RNG state. + +.. ocv:cfunction:: void cvRandArr( CvRNG* rng, CvArr* arr, int distType, CvScalar param1, CvScalar param2) +.. ocv:pyoldfunction:: cv.RandArr(rng, arr, distType, param1, param2)-> None + + :param rng: CvRNG state initialized by :ocv:cfunc:`RNG` + + :param arr: The destination array + + :param distType: 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. + +The function fills the destination array with uniformly or normally distributed random numbers. + +.. seealso:: :ocv:func:`randu`, :ocv:func:`randn`, :ocv:func:`RNG::fill`. + +RandInt +------- +Returns a 32-bit unsigned integer and updates RNG. + +.. ocv:cfunction:: unsigned cvRandInt(CvRNG* rng) +.. ocv:pyoldfunction:: cv.RandInt(rng)-> unsigned + + :param rng: CvRNG state initialized by :ocv:cfunc:`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. + + +RandReal +-------- +Returns a floating-point random number and updates RNG. + +.. ocv:cfunction:: double cvRandReal(CvRNG* rng) +.. ocv:pyoldfunction:: cv.RandReal(rng)-> double + + :param rng: RNG state initialized by :ocv:cfunc:`RNG` + +The function returns a uniformly-distributed random floating-point number between 0 and 1 (1 is not included). + + +fromarray +--------- +Create a CvMat from an object that supports the array interface. + +.. ocv:pyoldfunction:: cv.fromarray(object, allowND=False) -> CvMat + + :param object: Any object that supports the array interface + + :param allowND: If true, will return a CvMatND + +If the object supports the `array interface `_ +, +return a :ocv:struct:`CvMat` or :ocv:struct:`CvMatND`, depending on ``allowND`` flag: + + * If ``allowND = False``, then the object's array must be either 2D or 3D. If it is 2D, then the returned CvMat has a single channel. If it is 3D, then the returned CvMat will have N channels, where N is the last dimension of the array. In this case, N cannot be greater than OpenCV's channel limit, ``CV_CN_MAX``. + + * If``allowND = True``, then ``fromarray`` returns a single-channel :ocv:struct:`CvMatND` with the same shape as the original array. + +For example, `NumPy `_ arrays support the array interface, so can be converted to OpenCV objects: + +.. code-block::python + + >>> import cv, numpy + >>> a = numpy.ones((480, 640)) + >>> mat = cv.fromarray(a) + >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) + (480, 640) 1 + >>> a = numpy.ones((480, 640, 3)) + >>> mat = cv.fromarray(a) + >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) + (480, 640) 3 + >>> a = numpy.ones((480, 640, 3)) + >>> mat = cv.fromarray(a, allowND = True) + >>> print cv.GetDims(mat), cv.CV_MAT_CN(cv.GetElemType(mat)) + (480, 640, 3) 1 + +.. note:: In the new Python wrappers (**cv2** module) the function is not needed, since cv2 can process Numpy arrays (and this is the only supported array type). + diff --git a/modules/core/doc/old_xml_yaml_persistence.rst b/modules/core/doc/old_xml_yaml_persistence.rst new file mode 100644 index 0000000000..4c5f024fd4 --- /dev/null +++ b/modules/core/doc/old_xml_yaml_persistence.rst @@ -0,0 +1,909 @@ +XML/YAML Persistence (C API) +============================== + +The section describes the OpenCV 1.x API for reading and writing data structures to/from XML or YAML files. It is now recommended to use the new C++ interface for reading and writing data. + +.. highlight:: c + +CvFileStorage +------------- + +.. ocv:struct:: CvFileStorage + +The structure ``CvFileStorage`` is a "black box" representation of the file storage associated with a file on disk. Several functions that are described below take ``CvFileStorage*`` as inputs and allow the user to save or to load hierarchical collections that consist of scalar values, standard CXCore objects (such as matrices, sequences, graphs), and user-defined objects. + +OpenCV can read and write data in XML (http://www.w3c.org/XML) or YAML +(http://www.yaml.org) formats. Below is an example of 3x3 floating-point identity matrix ``A``, stored in XML and YAML files using CXCore functions: + +XML: :: + + + + + 3 + 3 +
    f
    + 1. 0. 0. 0. 1. 0. 0. 0. 1. +
    + + +YAML: :: + + %YAML:1.0 + A: !!opencv-matrix + rows: 3 + cols: 3 + dt: f + data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.] + +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. + +CvFileNode +---------- + +.. ocv:struct:: CvFileNode + +File storage node. 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. Collections are also referenced to as "structures" in the data writing functions. There can be named collections (mappings), where each element has a name and is accessed by a name, and ordered collections (sequences), where elements do not have names, but rather accessed by index. + + .. ocv:member:: int tag + + type of the file node: + + * CV_NODE_NONE - empty node + * CV_NODE_INT - an integer + * CV_NODE_REAL - a floating-point number + * CV_NODE_STR - text string + * CV_NODE_SEQ - a sequence + * CV_NODE_MAP - a mapping + + type of the node can be retrieved using ``CV_NODE_TYPE(node->tag)`` macro. + + .. ocv:member:: CvTypeInfo* info + + optional pointer to the user type information. If you look at the matrix representation in XML and YAML, shown above, you may notice ``type_id="opencv-matrix"`` or ``!!opencv-matrix`` strings. They are used to specify that the certain element of a file is a representation of a data structure of certain type ("opencv-matrix" corresponds to :ocv:struct:`CvMat`). When a file is parsed, such type identifiers are passed to :ocv:cfunc:`FindType` to find type information and the pointer to it is stored in the file node. See :ocv:struct:`CvTypeInfo` for more details. + + .. ocv:member:: union data + + the node data, declared as: :: + + union + { + double f; /* scalar floating-point number */ + int i; /* scalar integer number */ + CvString str; /* text string */ + CvSeq* seq; /* sequence (ordered collection of file nodes) */ + struct CvMap* map; /* map (collection of named file nodes) */ + } data; + + .. + + Primitive nodes are read using :ocv:cfunc:`ReadInt`, :ocv:cfunc:`ReadReal` and :ocv:cfunc:`ReadString`. Sequences are read by iterating through ``node->data.seq`` (see "Dynamic Data Structures" section). Mappings are read using :ocv:cfunc:`GetFileNodeByName`. Nodes with the specified type (so that ``node->info != NULL``) can be read using :ocv:cfunc:`Read`. + +CvAttrList +---------- + +.. ocv:struct:: CvAttrList + +List of attributes. :: + + 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 */ + } + CvAttrList; + + /* initializes CvAttrList structure */ + inline CvAttrList cvAttrList( const char** attr=NULL, CvAttrList* next=NULL ); + + /* returns attribute value or 0 (NULL) if there is no such attribute */ + const char* cvAttrValue( const CvAttrList* attr, const char* attr_name ); + +.. + +In the current implementation, attributes are used to pass extra parameters when writing user objects (see +:ocv:cfunc:`Write`). XML attributes inside tags are not supported, aside from the object type specification (``type_id`` attribute). + +CvTypeInfo +---------- + +.. ocv:struct:: CvTypeInfo + +Type information. :: + + typedef int (CV_CDECL *CvIsInstanceFunc)( const void* structPtr ); + typedef void (CV_CDECL *CvReleaseFunc)( void** structDblPtr ); + typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node ); + typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, + const char* name, + const void* structPtr, + CvAttrList attributes ); + typedef void* (CV_CDECL *CvCloneFunc)( const void* structPtr ); + + typedef struct CvTypeInfo + { + int flags; /* not used */ + int header_size; /* sizeof(CvTypeInfo) */ + struct CvTypeInfo* prev; /* previous registered type in the list */ + struct CvTypeInfo* next; /* next registered type in the list */ + const char* type_name; /* type name, written to file storage */ + + /* methods */ + CvIsInstanceFunc is_instance; /* checks if the passed object belongs to the type */ + CvReleaseFunc release; /* releases object (memory etc.) */ + CvReadFunc read; /* reads object from file storage */ + CvWriteFunc write; /* writes object to file storage */ + CvCloneFunc clone; /* creates a copy of the object */ + } + CvTypeInfo; + +.. + +The structure contains information about one of the standard or user-defined types. Instances of the type may or may not contain a pointer to the corresponding :ocv:struct:`CvTypeInfo` structure. In any case, there is a way to find the type info structure for a given object using the :ocv:cfunc:`TypeOf` function. Aternatively, type info can be found by type name using :ocv:cfunc:`FindType`, which is used when an object is read from file storage. The user can register a new type with :ocv:cfunc:`RegisterType` +that adds the type information structure into the beginning of the type list. Thus, it is possible to create specialized types from generic standard types and override the basic methods. + +Clone +----- +Makes a clone of an object. + +.. ocv:cfunction:: void* cvClone( const void* structPtr ) + + :param structPtr: The object to clone + +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, ``structPtr`` is ``CvMat*``, it is faster to call the specific function, like :ocv:cfunc:`CloneMat`. + +EndWriteStruct +-------------- +Finishes writing to a file node collection. + +.. ocv:cfunction:: void cvEndWriteStruct(CvFileStorage* fs) + + :param fs: File storage + +.. seealso:: :ocv:cfunc:`StartWriteStruct`. + +FindType +-------- +Finds a type by its name. + +.. ocv:cfunction:: CvTypeInfo* cvFindType(const char* typeName) + + :param typeName: Type name + +The function finds a registered type by its name. It returns NULL if there is no type with the specified name. + +FirstType +--------- +Returns the beginning of a type list. + +.. ocv:cfunction:: CvTypeInfo* cvFirstType(void) + +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 :ocv:struct:`CvTypeInfo` structure. + +GetFileNode +----------- +Finds a node in a map or file storage. + +.. ocv:cfunction:: CvFileNode* cvGetFileNode( CvFileStorage* fs, CvFileNode* map, const CvStringHashNode* key, int createMissing=0 ) + + :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 :ocv:cfunc:`GetHashedKey` + + :param createMissing: Flag that specifies whether an absent node should be added to the map + +The function finds a file node. It is a faster version of :ocv:cfunc:`GetFileNodeByName` +(see :ocv:cfunc:`GetHashedKey` discussion). Also, the function can insert a new node, if it is not in the map yet. + +GetFileNodeByName +----------------- +Finds a node in a map or file storage. + +.. ocv:cfunction:: CvFileNode* cvGetFileNodeByName( const CvFileStorage* fs, const CvFileNode* map, const char* name) + + :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 + +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 :ocv:cfunc:`GetSeqElem` +(or sequence reader) for sequences, it is possible to nagivate 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 :ocv:cfunc:`GetHashedKey` and :ocv:cfunc:`GetFileNode`. + +GetFileNodeName +--------------- +Returns the name of a file node. + +.. ocv:cfunction:: const char* cvGetFileNodeName( const CvFileNode* node ) + + :param node: 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``. + +GetHashedKey +------------ +Returns a unique pointer for a given name. + +.. ocv:cfunction:: CvStringHashNode* cvGetHashedKey( CvFileStorage* fs, const char* name, int len=-1, int createMissing=0 ) + + :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 createMissing: Flag that specifies, whether an absent key should be added into the hash table + +The function returns a unique pointer for each particular file node name. This pointer can be then passed to the :ocv:cfunc:`GetFileNode` function that is faster than :ocv:cfunc:`GetFileNodeByName` +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: :: + + points: + - { x: 10, y: 10 } + - { x: 20, y: 20 } + - { x: 30, y: 30 } + # ... + +.. + +Then, it is possible to get hashed "x" and "y" pointers to speed up decoding of the points. :: + + #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 /* default value */ ); + int y = cvReadIntByName( fs, pt, "y", 0 /* default value */ ); + #endif + CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); + printf(" + } + } + cvReleaseFileStorage( &fs ); + return 0; + } +.. + +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. + +GetRootFileNode +--------------- +Retrieves one of the top-level nodes of the file storage. + +.. ocv:cfunction:: CvFileNode* cvGetRootFileNode( const CvFileStorage* fs, int stream_index=0 ) + + :param fs: File storage + + :param stream_index: Zero-based index of the stream. See :ocv:cfunc:`StartNextStream` . In most cases, there is only one stream in the file; however, there can be several. + +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. + + +Load +---- +Loads an object from a file. + +.. ocv:cfunction:: void* cvLoad( const char* filename, CvMemStorage* storage=NULL, const char* name=NULL, const char** realName=NULL ) +.. ocv:pyoldfunction:: cv.Load(filename, storage=None, name=None)-> generic + + :param filename: File name + + :param storage: Memory storage for dynamic structures, such as :ocv:struct:`CvSeq` or :ocv:struct:`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 realName: Optional output parameter that will contain the name of the loaded object (useful if ``name=NULL`` ) + +The function loads an object from a file. It basically reads the specified file, find the first top-level node and calls :ocv:cfunc:`Read` 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. + +OpenFileStorage +--------------- +Opens file storage for reading or writing data. + +.. ocv:cfunction:: CvFileStorage* cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, int flags) + + :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 :ocv:struct:`CvSeq` or :ocv:struct:`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 + +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 :ocv:struct:`CvFileStorage` structure. + +Read +---- +Decodes an object and returns a pointer to it. + +.. ocv:cfunction:: void* cvRead( CvFileStorage* fs, CvFileNode* node, CvAttrList* attributes=NULL ) + + :param fs: File storage + + :param node: The root object node + + :param attributes: Unused parameter + +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 :ocv:struct:`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 :ocv:cfunc:`OpenFileStorage` or, if a NULL pointer was passed, in temporary +memory storage, which is released when :ocv:cfunc:`ReleaseFileStorage` 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 :ocv:cfunc:`Release`. + +ReadByName +---------- +Finds an object by name and decodes it. + +.. ocv:cfunction:: void* cvReadByName( CvFileStorage* fs, const CvFileNode* map, const char* name, CvAttrList* attributes=NULL ) + + :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 + +The function is a simple superposition of :ocv:cfunc:`GetFileNodeByName` and :ocv:cfunc:`Read`. + +ReadInt +------- +Retrieves an integer value from a file node. + +.. ocv:cfunction:: int cvReadInt( const CvFileNode* node, int defaultValue=0 ) + + :param node: File node + + :param defaultValue: The value that is returned if ``node`` is NULL + +The function returns an integer that is represented by the file node. If the file node is NULL, the +``defaultValue`` is returned (thus, it is convenient to call the function right after :ocv:cfunc:`GetFileNode` 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. + +ReadIntByName +------------- +Finds a file node and returns its value. + +.. ocv:cfunction:: int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, int defaultValue=0 ) + + :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 defaultValue: The value that is returned if the file node is not found + +The function is a simple superposition of :ocv:cfunc:`GetFileNodeByName` and :ocv:cfunc:`ReadInt`. + +ReadRawData +----------- +Reads multiple numbers. + +.. ocv:cfunction:: void cvReadRawData( const CvFileStorage* fs, const CvFileNode* src, void* dst, const char* dt) + + :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 :ocv:cfunc:`WriteRawData` . + +The function reads elements from a file node that represents a sequence of scalars. + + +ReadRawDataSlice +---------------- +Initializes file node sequence reader. + +.. ocv:cfunction:: void cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, int count, void* dst, const char* dt ) + + :param fs: File storage + + :param reader: The sequence reader. Initialize it with :ocv:cfunc:`StartReadRawData` . + + :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 :ocv:cfunc:`WriteRawData` . + +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 :ocv:cfunc:`SetSeqReaderPos`. + +ReadReal +-------- +Retrieves a floating-point value from a file node. + +.. ocv:cfunction:: double cvReadReal( const CvFileNode* node, double defaultValue=0. ) + + :param node: File node + + :param defaultValue: The value that is returned if ``node`` is NULL + +The function returns a floating-point value +that is represented by the file node. If the file node is NULL, the +``defaultValue`` +is returned (thus, it is convenient to call +the function right after +:ocv:cfunc:`GetFileNode` +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. + + +ReadRealByName +-------------- +Finds a file node and returns its value. + +.. ocv:cfunction:: double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, double defaultValue=0.) + + :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 defaultValue: The value that is returned if the file node is not found + +The function is a simple superposition of +:ocv:cfunc:`GetFileNodeByName` +and +:ocv:cfunc:`ReadReal` +. + + +ReadString +---------- +Retrieves a text string from a file node. + +.. ocv:cfunction:: const char* cvReadString( const CvFileNode* node, const char* defaultValue=NULL ) + + :param node: File node + + :param defaultValue: The value that is returned if ``node`` is NULL + +The function returns a text string that is represented +by the file node. If the file node is NULL, the +``defaultValue`` +is returned (thus, it is convenient to call the function right after +:ocv:cfunc:`GetFileNode` +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. + + +ReadStringByName +---------------- +Finds a file node by its name and returns its value. + +.. ocv:cfunction:: const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, const char* defaultValue=NULL ) + + :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 defaultValue: The value that is returned if the file node is not found + +The function is a simple superposition of +:ocv:cfunc:`GetFileNodeByName` +and +:ocv:cfunc:`ReadString` +. + + +RegisterType +------------ +Registers a new type. + +.. ocv:cfunction:: void cvRegisterType(const CvTypeInfo* info) + + :param info: Type info structure + +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. + + +Release +------- +Releases an object. + +.. ocv:cfunction:: void cvRelease( void** structPtr ) + + :param structPtr: Double pointer to the object + +The function finds the type of a given object and calls +``release`` +with the double pointer. + + +ReleaseFileStorage +------------------ +Releases file storage. + +.. ocv:cfunction:: void cvReleaseFileStorage(CvFileStorage** fs) + + :param fs: Double pointer to the released 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. + + +Save +---- +Saves an object to a file. + +.. ocv:cfunction:: void cvSave( const char* filename, const void* structPtr, const char* name=NULL, const char* comment=NULL, CvAttrList attributes=cvAttrList()) +.. ocv:pyoldfunction:: cv.Save(filename, structPtr, name=None, comment=None)-> None + + :param filename: File name + + :param structPtr: 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 :ocv:cfunc:`Write` + +The function saves an object to a file. It provides a simple interface to +:ocv:cfunc:`Write` +. + + +StartNextStream +--------------- +Starts the next stream. + +.. ocv:cfunction:: void cvStartNextStream(CvFileStorage* fs) + + :param fs: File storage + +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: :: + + + + + + + +... + +The a YAML file will look like this: +%YAML:1.0 +# stream #1 data +... +--- +# stream #2 data + +This is useful for concatenating files or for resuming the writing process. + + +StartReadRawData +---------------- +Initializes the file node sequence reader. + +.. ocv:cfunction:: void cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src, CvSeqReader* reader) + + :param fs: File storage + + :param src: The file node (a sequence) to read numbers from + + :param reader: Pointer to the sequence reader + +The function initializes the sequence reader to read data from a file node. The initialized reader can be then passed to :ocv:cfunc:`ReadRawDataSlice`. + + +StartWriteStruct +---------------- +Starts writing a new structure. + +.. ocv:cfunction:: void cvStartWriteStruct( CvFileStorage* fs, const char* name, int struct_flags, const char* typeName=NULL, CvAttrList attributes=cvAttrList()) + + :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 :ocv:struct:`CvFileStorage` ), that is, its elements do not have a name. + + * **CV_NODE_MAP** the written structure is a map (see discussion of :ocv:struct:`CvFileStorage` ), that is, all its elements have names. + + One and only one of the two above flags must be specified + + :param 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 typeName: 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 :ocv:struct:`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 :ocv:struct:`CvTypeInfo` and :ocv:cfunc:`FindTypeInfo` ). + + :param attributes: This parameter is not used in the current implementation + +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, :ocv:cfunc:`EndWriteStruct` should be called. The function can be used to group some objects or to implement the ``write`` function for a some user object (see :ocv:struct:`CvTypeInfo`). + + +TypeOf +------ +Returns the type of an object. + +.. ocv:cfunction:: CvTypeInfo* cvTypeOf( const void* structPtr ) + + :param structPtr: The object pointer + +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. + + +UnregisterType +-------------- +Unregisters the type. + +.. ocv:cfunction:: void cvUnregisterType( const char* typeName ) + + :param typeName: Name of an unregistered 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 :ocv:cfunc:`TypeOf` or by iterating the type list, starting from :ocv:cfunc:`FirstType`, and then calling ``cvUnregisterType(info->typeName)``. + + +Write +----- +Writes an object to file storage. + +.. ocv:cfunction:: void cvWrite( CvFileStorage* fs, const char* name, const void* ptr, CvAttrList attributes=cvAttrList() ) + + :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 dicsussion below). + +The function writes an object to file storage. First, the appropriate type info is found using :ocv:cfunc:`TypeOf`. 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 :ocv:cfunc:`WriteRawData`): + +#. + 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: + +:: + + #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; + } + +.. + + +WriteComment +------------ +Writes a comment. + +.. ocv:cfunction:: void cvWriteComment( CvFileStorage* fs, const char* comment, int eolComment) + + :param fs: File storage + + :param comment: The written comment, single-line or multi-line + + :param eolComment: 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. + +The function writes a comment into file storage. The comments are skipped when the storage is read. + +WriteFileNode +------------- +Writes a file node to another file storage. + +.. ocv:cfunction:: void cvWriteFileNode( CvFileStorage* fs, const char* new_node_name, const CvFileNode* node, int embed ) + + :param fs: Destination file storage + + :param new_file_node: New name of the file node in the destination file storage. To keep the existing name, use :ocv:cfunc:`cvGetFileNodeName` + + :param node: The written node + + :param embed: If the written node is a collection and this parameter is not zero, no extra level of hiararchy 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. + +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. + +WriteInt +-------- +Writes an integer value. + +.. ocv:cfunction:: void cvWriteInt( CvFileStorage* fs, const char* name, int value) + + :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 + +The function writes a single integer value (with or without a name) to the file storage. + + +WriteRawData +------------ +Writes multiple numbers. + +.. ocv:cfunction:: void cvWriteRawData( CvFileStorage* fs, const void* src, int len, const char* dt ) + + :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 that has the following format ``([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. + +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 +:ocv:cfunc:`WriteInt` +and +:ocv:cfunc:`WriteReal` +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. + + +WriteReal +--------- +Writes a floating-point value. + +.. ocv:cfunction:: void cvWriteReal( CvFileStorage* fs, const char* name, double value ) + + :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 + +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. :: + + 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 ); + } + +.. + + +WriteString +----------- +Writes a text string. + +.. ocv:cfunction:: void cvWriteString( CvFileStorage* fs, const char* name, const char* str, int quote=0 ) + + :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). + +The function writes a text string to file storage. diff --git a/modules/core/doc/operations_on_arrays.rst b/modules/core/doc/operations_on_arrays.rst index fa6c1cf39a..1d5f9379a8 100644 --- a/modules/core/doc/operations_on_arrays.rst +++ b/modules/core/doc/operations_on_arrays.rst @@ -488,9 +488,9 @@ Performs the per-element comparison of two arrays or an array and scalar value. .. ocv:pyoldfunction:: cv.CmpS(src1, src2, dst, cmpOp)-> None - :param src1: First source array or a scalar (in the case of ``cvCmp``, ``cv.Cmp``, ``cvCmpS``, ``cv.CmpS`` it is always an array) + :param src1: First source array or a scalar (in the case of ``cvCmp``, ``cv.Cmp``, ``cvCmpS``, ``cv.CmpS`` it is always an array). When it is array, it must have a single channel. - :param src2: Second source array or a scalar (in the case of ``cvCmp`` and ``cv.Cmp`` it is always an array; in the case of ``cvCmpS``, ``cv.CmpS`` it is always a scalar) + :param src2: Second source array or a scalar (in the case of ``cvCmp`` and ``cv.Cmp`` it is always an array; in the case of ``cvCmpS``, ``cv.CmpS`` it is always a scalar). When it is array, it must have a single channel. :param dst: Destination array that has the same size as the input array(s) and type= ``CV_8UC1`` . @@ -647,24 +647,6 @@ The function returns the number of non-zero elements in ``mtx`` : -cubeRoot --------- -Computes the cube root of an argument. - -.. ocv:function:: float cubeRoot(float val) - -.. ocv:pyfunction:: cv2.cubeRoot(val) -> retval - -.. ocv:cfunction:: float cvCbrt(float val) - -.. ocv:pyoldfunction:: cv.Cbrt(val)-> float - - :param val: A function argument. - -The function ``cubeRoot`` computes :math:`\sqrt[3]{\texttt{val}}`. Negative arguments are handled correctly. NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for single-precision data. - - - cvarrToMat ---------- Converts ``CvMat``, ``IplImage`` , or ``CvMatND`` to ``Mat``. @@ -1135,25 +1117,6 @@ To extract a channel from a new-style matrix, use -fastAtan2 ---------- -Calculates the angle of a 2D vector in degrees. - -.. ocv:function:: float fastAtan2(float y, float x) - -.. ocv:pyfunction:: cv2.fastAtan2(y, x) -> retval - -.. ocv:cfunction:: float cvFastArctan(float y, float x) -.. ocv:pyoldfunction:: cv.FastArctan(y, x)-> float - - :param x: x-coordinate of the vector. - - :param y: y-coordinate of the vector. - -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. - - - flip -------- Flips a 2D array around vertical, horizontal, or both axes. @@ -1553,7 +1516,9 @@ Calculates the Mahalanobis distance between two vectors. .. ocv:pyfunction:: cv2.Mahalanobis(v1, v2, icovar) -> retval -.. ocv:cfunction:: double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat) +.. ocv:cfunction:: double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* icovar) + +.. ocv:pyoldfunction:: cv.Mahalanobis(vec1, vec2, icovar)-> None :param vec1: First 1D source vector. @@ -1561,7 +1526,7 @@ Calculates the Mahalanobis distance between two vectors. :param icovar: Inverse covariance matrix. -The function ``Mahalonobis`` calculates and returns the weighted distance between two vectors: +The function ``Mahalanobis`` calculates and returns the weighted distance between two vectors: .. math:: @@ -2217,6 +2182,8 @@ Performs Principal Component Analysis of the supplied dataset. .. ocv:function:: PCA& PCA::operator()(InputArray data, InputArray mean, int flags, int maxComponents=0) +.. ocv:pyfunction:: cv2.PCACompute(data[, mean[, eigenvectors[, maxComponents]]]) -> mean, eigenvectors + :param data: Input samples stored as the matrix rows or as the matrix columns. :param mean: Optional mean value. If the matrix is empty ( ``Mat()`` ), the mean is computed from the data. @@ -2243,6 +2210,8 @@ Projects vector(s) to the principal component subspace. .. ocv:function:: void PCA::project(InputArray vec, OutputArray result) const +.. ocv:pyfunction:: cv2.PCAProject(vec, mean, eigenvectors[, result]) -> result + :param vec: Input vector(s). They must have the same dimensionality and the same layout as the input data used at PCA phase. That is, if ``CV_PCA_DATA_AS_ROWS`` are specified, then ``vec.cols==data.cols`` (vector dimensionality) and ``vec.rows`` is the number of vectors to project. The same is true for the ``CV_PCA_DATA_AS_COLS`` case. :param result: Output vectors. In case of ``CV_PCA_DATA_AS_COLS`` , 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). @@ -2259,6 +2228,8 @@ Reconstructs vectors from their PC projections. .. ocv:function:: void PCA::backProject(InputArray vec, OutputArray result) const +.. ocv:pyfunction:: cv2.PCABackProject(vec, mean, eigenvectors[, result]) -> result + :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. @@ -2719,35 +2690,6 @@ The second variant of the function is more convenient to use with -saturate_cast -------------- -Template function for accurate conversion from one primitive type to another. - -.. ocv:function:: template<...> _Tp saturate_cast(_Tp2 v) - - :param v: Function parameter. - -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: :: - - uchar a = saturate_cast(-100); // a = 0 (UCHAR_MIN) - short b = saturate_cast(33333.33333); // b = 32767 (SHRT_MAX) - -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. - -.. seealso:: - - :ocv:func:`add`, - :ocv:func:`subtract`, - :ocv:func:`multiply`, - :ocv:func:`divide`, - :ocv:func:`Mat::convertTo` - - - scaleAdd -------- Calculates the sum of a scaled array and another array. @@ -3161,7 +3103,7 @@ The constructors. .. ocv:function:: SVD::SVD( InputArray A, int flags=0 ) - :param A: Decomposed matrix. + :param src: Decomposed matrix. :param flags: Operation flags. @@ -3175,14 +3117,13 @@ The first constructor initializes an empty ``SVD`` structure. The second constru :ocv:func:`SVD::operator ()` . - SVD::operator () ---------------- Performs SVD of a matrix. -.. ocv:function:: SVD& SVD::operator ()( InputArray A, int flags=0 ) +.. ocv:function:: SVD& SVD::operator()( InputArray src, int flags=0 ) - :param A: Decomposed matrix. + :param src: Decomposed matrix. :param flags: Operation flags. @@ -3196,35 +3137,81 @@ The operator performs the singular value decomposition of the supplied matrix. T :ocv:func:`Mat::create` . +SVD::compute +------------ +Performs SVD of a matrix + +.. ocv:function:: static void SVD::compute( InputArray src, OutputArray w, OutputArray u, OutputArray vt, int flags=0 ) + +.. ocv:function:: static void SVD::compute( InputArray src, OutputArray w, int flags=0 ) + +.. ocv:pyfunction:: cv2.SVDecomp(src[, w[, u[, vt[, flags]]]]) -> w, u, vt + +.. ocv:cfunction:: void cvSVD( CvArr* src, CvArr* w, CvArr* u=NULL, CvArr* v=NULL, int flags=0) + +.. ocv:pyoldfunction:: cv.SVD(src, w, u=None, v=None, flags=0)-> None + + :param src: Decomposed matrix + + :param w: Computed singular values + + :param u: Computed left singular vectors + + :param v: Computed right singular vectors + + :param vt: Transposed matrix of right singular values + + :param flags: Opertion flags - see :ocv:func:`SVD::SVD`. + +The methods/functions perform SVD of matrix. Unlike ``SVD::SVD`` constructor and ``SVD::operator ()``, they store the results to the user-provided matrices. :: + + Mat A, w, u, vt; + SVD::compute(A, w, u, vt); + SVD::solveZ ----------- Solves an under-determined singular linear system. -.. ocv:function:: static void SVD::solveZ( InputArray A, OutputArray x ) +.. ocv:function:: static void SVD::solveZ( InputArray src, OutputArray dst ) - :param A: Left-hand-side matrix. + :param src: Left-hand-side matrix. - :param x: Found solution. + :param dst: Found solution. 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: .. math:: - x^* = \arg \min _{x: \| x \| =1} \| A \cdot x \| - + dst = \arg \min _{x: \| x \| =1} \| src \cdot x \| SVD::backSubst -------------- Performs a singular value back substitution. -.. ocv:function:: void SVD::backSubst( InputArray rhs, OutputArray x ) const +.. ocv:function:: void SVD::backSubst( InputArray rhs, OutputArray dst ) const - :param rhs: Right-hand side of a linear system ``A*x = rhs`` to be solved, where ``A`` has been previously decomposed using :ocv:func:`SVD::SVD` or :ocv:func:`SVD::operator ()` . +.. ocv:function:: static void SVD::backSubst( InputArray w, InputArray u, InputArray vt, InputArray rhs, OutputArray dst ) + +.. ocv:pyfunction:: cv2.SVBackSubst(w, u, vt, rhs[, dst]) -> dst + +.. ocv:cfunction:: void cvSVBkSb( const CvArr* w, const CvArr* u, const CvArr* v, const CvArr* rhs, CvArr* dst, int flags) + +.. ocv:pyoldfunction:: cv.SVBkSb(w, u, v, rhs, dst, flags)-> None + + :param w: Singular values - :param x: Found solution of the system. + :param u: Left singular vectors + + :param v: Right singular vectors + + :param vt: Transposed matrix of right singular vectors. + + :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. The method computes a back substitution for the specified right-hand side: @@ -3234,7 +3221,7 @@ The method computes a back substitution for the specified right-hand side: 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. -.. 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, ``A`` ). If all you need is to solve a single system (possibly with multiple ``rhs`` immediately available), simply call :ocv:func:`solve` add pass ``DECOMP_SVD`` there. It does absolutely the same thing. +.. 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 :ocv:func:`solve` add pass ``DECOMP_SVD`` there. It does absolutely the same thing. diff --git a/doc/pics/memstorage1.png b/modules/core/doc/pics/memstorage1.png similarity index 100% rename from doc/pics/memstorage1.png rename to modules/core/doc/pics/memstorage1.png diff --git a/doc/pics/memstorage2.png b/modules/core/doc/pics/memstorage2.png similarity index 100% rename from doc/pics/memstorage2.png rename to modules/core/doc/pics/memstorage2.png diff --git a/modules/core/doc/utility_and_system_functions_and_macros.rst b/modules/core/doc/utility_and_system_functions_and_macros.rst index 37b2d14345..6fa86cfc8d 100644 --- a/modules/core/doc/utility_and_system_functions_and_macros.rst +++ b/modules/core/doc/utility_and_system_functions_and_macros.rst @@ -67,6 +67,106 @@ The generic function ``deallocate`` deallocates the buffer allocated with +fastAtan2 +--------- +Calculates the angle of a 2D vector in degrees. + +.. ocv:function:: float fastAtan2(float y, float x) + +.. ocv:pyfunction:: cv2.fastAtan2(y, x) -> retval + +.. ocv:cfunction:: float cvFastArctan(float y, float x) +.. ocv:pyoldfunction:: cv.FastArctan(y, x)-> float + + :param x: x-coordinate of the vector. + + :param y: y-coordinate of the vector. + +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. + + +cubeRoot +-------- +Computes the cube root of an argument. + +.. ocv:function:: float cubeRoot(float val) + +.. ocv:pyfunction:: cv2.cubeRoot(val) -> retval + +.. ocv:cfunction:: float cvCbrt(float val) + +.. ocv:pyoldfunction:: cv.Cbrt(val)-> float + + :param val: A function argument. + +The function ``cubeRoot`` computes :math:`\sqrt[3]{\texttt{val}}`. Negative arguments are handled correctly. NaN and Inf are not handled. The accuracy approaches the maximum possible accuracy for single-precision data. + + +Ceil +----- +Rounds floating-point number to the nearest integer not smaller than the original. + +.. ocv:cfunction:: int cvCeil(double value) +.. ocv:pyoldfunction:: cv.Ceil(value) -> int + + :param value: floating-point number. If the value is outside of ``INT_MIN`` ... ``INT_MAX`` range, the result is not defined. + +The function computes an integer ``i`` such that: + +.. math:: + + i-1 < \texttt{value} \le i + + +Floor +----- +Rounds floating-point number to the nearest integer not larger than the original. + +.. ocv:cfunction:: int cvFloor(double value) +.. ocv:pyoldfunction:: cv.Floor(value) -> int + + :param value: floating-point number. If the value is outside of ``INT_MIN`` ... ``INT_MAX`` range, the result is not defined. + +The function computes an integer ``i`` such that: + +.. math:: + + i \le \texttt{value} < i+1 + + +Round +----- +Rounds floating-point number to the nearest integer + +.. ocv:cfunction:: int cvRound(double value) +.. ocv:pyoldfunction:: cv.Round(value) -> int + + :param value: floating-point number. If the value is outside of ``INT_MIN`` ... ``INT_MAX`` range, the result is not defined. + + +IsInf +----- +Determines if the argument is Infinity. + +.. ocv:cfunction:: int cvIsInf(double value) +.. ocv:pyoldfunction:: cv.IsInf(value)-> int + + :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. + +IsNaN +----- +Determines if the argument is Not A Number. + +.. ocv:cfunction:: int cvIsNaN(double value) +.. ocv:pyoldfunction:: cv.IsNaN(value)-> int + + :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_Assert --------- Checks a condition at runtime and throws exception if it fails @@ -145,6 +245,7 @@ fastMalloc Allocates an aligned memory buffer. .. ocv:function:: void* fastMalloc(size_t size) +.. ocv:cfunction:: void* cvAlloc( size_t size ) :param size: Allocated buffer size. @@ -157,13 +258,13 @@ fastFree Deallocates a memory buffer. .. ocv:function:: void fastFree(void* ptr) +.. ocv:cfunction:: void cvFree( void** pptr ) :param ptr: Pointer to the allocated buffer. + + :param pptr: Double pointer to the allocated buffer -The function deallocates the buffer allocated with -:ocv:func:`fastMalloc` . -If NULL pointer is passed, the function does nothing. - +The function deallocates the buffer allocated with :ocv:func:`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. format @@ -249,6 +350,32 @@ 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. +saturate_cast +------------- +Template function for accurate conversion from one primitive type to another. + +.. ocv:function:: template<...> _Tp saturate_cast(_Tp2 v) + + :param v: Function parameter. + +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: :: + + uchar a = saturate_cast(-100); // a = 0 (UCHAR_MIN) + short b = saturate_cast(33333.33333); // b = 32767 (SHRT_MAX) + +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. + +.. seealso:: + + :ocv:func:`add`, + :ocv:func:`subtract`, + :ocv:func:`multiply`, + :ocv:func:`divide`, + :ocv:func:`Mat::convertTo` setNumThreads ----------------- diff --git a/modules/core/doc/xml_yaml_persistence.rst b/modules/core/doc/xml_yaml_persistence.rst index e08a0277f8..93532e43d6 100644 --- a/modules/core/doc/xml_yaml_persistence.rst +++ b/modules/core/doc/xml_yaml_persistence.rst @@ -162,5 +162,3 @@ FileNodeIterator .. ocv:class:: FileNodeIterator The class ``FileNodeIterator`` is used to iterate through sequences 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. - - diff --git a/modules/features2d/doc/common_interfaces_of_feature_detectors.rst b/modules/features2d/doc/common_interfaces_of_feature_detectors.rst index f8a747ae1c..bc0984a603 100644 --- a/modules/features2d/doc/common_interfaces_of_feature_detectors.rst +++ b/modules/features2d/doc/common_interfaces_of_feature_detectors.rst @@ -12,57 +12,60 @@ KeyPoint -------- .. ocv:class:: KeyPoint -Data structure for salient point detectors. :: +Data structure for salient point detectors. - class KeyPoint - { - public: - // the default constructor - KeyPoint() : pt(0,0), size(0), angle(-1), response(0), octave(0), - class_id(-1) {} - // the full constructor - KeyPoint(Point2f _pt, float _size, float _angle=-1, - float _response=0, int _octave=0, int _class_id=-1) - : pt(_pt), size(_size), angle(_angle), response(_response), - octave(_octave), class_id(_class_id) {} - // another form of the full constructor - KeyPoint(float x, float y, float _size, float _angle=-1, - float _response=0, int _octave=0, int _class_id=-1) - : pt(x, y), size(_size), angle(_angle), response(_response), - octave(_octave), class_id(_class_id) {} - // converts vector of keypoints to vector of points - static void convert(const std::vector& keypoints, - std::vector& points2f, - const std::vector& keypointIndexes=std::vector()); - // converts vector of points to the vector of keypoints, where each - // keypoint is assigned to the same size and the same orientation - static void convert(const std::vector& points2f, - std::vector& keypoints, - float size=1, float response=1, int octave=0, - int class_id=-1); + .. ocv:member:: Point2f pt + + coordinates of the keypoint + + .. ocv:member:: float size + + diameter of the meaningful keypoint neighborhood + + .. ocv:member:: float angle + + computed orientation of the keypoint (-1 if not applicable) + + .. ocv:member:: float response + + the response by which the most strong keypoints have been selected. Can be used for further sorting or subsampling + + .. ocv:member:: int octave + + octave (pyramid layer) from which the keypoint has been extracted + + .. ocv:member:: int class_id + + object id that can be used to clustered keypoints by an object they belong to - // 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 a circle) - static float overlap(const KeyPoint& kp1, const KeyPoint& kp2); +KeyPoint::KeyPoint +------------------ +The keypoint constructors - Point2f pt; // coordinates of the keypoints - float size; // diameter of the meaningful keypoint neighborhood - float angle; // computed orientation of the keypoint (-1 if not applicable) - float response; // the response by which the most strong keypoints - // have been selected. Can be used for further sorting - // or subsampling - int octave; // octave (pyramid layer) from which the keypoint has been extracted - int class_id; // object class (if the keypoints need to be clustered by - // an object they belong to) - }; +.. ocv:function:: KeyPoint::KeyPoint() - // writes vector of keypoints to the file storage - void write(FileStorage& fs, const string& name, const vector& keypoints); - // reads vector of keypoints from the specified file storage node - void read(const FileNode& node, CV_OUT vector& keypoints); +.. ocv:function:: KeyPoint::KeyPoint(Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1) + +.. ocv:function:: KeyPoint::KeyPoint(float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1) + +.. ocv:pyfunction:: cv2.KeyPoint(x, y, _size[, _angle[, _response[, _octave[, _class_id]]]]) -> + + :param x: x-coordinate of the keypoint + + :param y: y-coordinate of the keypoint + + :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 -.. FeatureDetector --------------- diff --git a/modules/features2d/doc/feature_detection_and_description.rst b/modules/features2d/doc/feature_detection_and_description.rst index aa5764836b..fd83387424 100644 --- a/modules/features2d/doc/feature_detection_and_description.rst +++ b/modules/features2d/doc/feature_detection_and_description.rst @@ -3,8 +3,6 @@ Feature Detection and Description .. highlight:: cpp - - FAST -------- Detects corners using the FAST algorithm @@ -52,37 +50,47 @@ StarDetector ------------ .. ocv:class:: StarDetector -Class implementing the ``Star`` keypoint detector. :: +Class implementing the ``Star`` keypoint detector, a modified version of the ``CenSurE`` keypoint detector described in [Agrawal08]_. - class StarDetector : CvStarDetectorParams - { - public: - // default constructor - StarDetector(); - // the full constructor that initializes all the algorithm parameters: - // maxSize - maximum size of the features. The following - // values of the parameter are supported: - // 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128 - // responseThreshold - threshold for the approximated laplacian, - // used to eliminate weak features. The larger it is, - // the less features will be retrieved - // lineThresholdProjected - another threshold for the laplacian to - // eliminate edges - // lineThresholdBinarized - another threshold for the feature - // size to eliminate edges. - // The larger the 2nd threshold, the more points you get. - StarDetector(int maxSize, int responseThreshold, - int lineThresholdProjected, - int lineThresholdBinarized, - int suppressNonmaxSize); +.. [Agrawal08] Agrawal, M. and Konolige, K. and Blas, M.R. "CenSurE: Center Surround Extremas for Realtime Feature Detection and Matching", ECCV08, 2008 - // finds keypoints in an image - void operator()(const Mat& image, vector& keypoints) const; - }; +StarDetector::StarDetector +-------------------------- +The Star Detector constructor -The class implements a modified version of the ``CenSurE`` keypoint detector described in -[Agrawal08]. +.. ocv:function:: StarDetector::StarDetector() +.. ocv:function:: StarDetector::StarDetector(int maxSize, int responseThreshold, int lineThresholdProjected, int lineThresholdBinarized, int suppressNonmaxSize) + +.. ocv:pyfunction:: cv2.StarDetector(maxSize, responseThreshold, lineThresholdProjected, lineThresholdBinarized, suppressNonmaxSize) -> + + :param maxSize: maximum size of the features. The following values are supported: 4, 6, 8, 11, 12, 16, 22, 23, 32, 45, 46, 64, 90, 128. In the case of a different value the result is undefined. + + :param responseThreshold: threshold for the approximated laplacian, used to eliminate weak features. The larger it is, the less features will be retrieved + + :param lineThresholdProjected: another threshold for the laplacian to eliminate edges + + :param lineThresholdBinarized: yet another threshold for the feature size to eliminate edges. The larger the 2nd threshold, the more points you get. + +StarDetector::operator() +------------------------ +Finds keypoints in an image + +.. ocv:function:: void StarDetector::operator()(const Mat& image, vector& keypoints) + +.. ocv:pyfunction:: cv2.StarDetector.detect(image) -> keypoints + +.. ocv:cfunction:: CvSeq* cvGetStarKeypoints( const CvArr* image, CvMemStorage* storage, CvStarDetectorParams params=cvStarDetectorParams() ) + +.. ocv:pyoldfunction:: cv.GetStarKeypoints(image, storage, params)-> keypoints + + :param image: The input 8-bit grayscale image + + :param keypoints: The output vector of keypoints + + :param storage: The memory storage used to store the keypoints (OpenCV 1.x API only) + + :param params: The algorithm parameters stored in ``CvStarDetectorParams`` (OpenCV 1.x API only) SIFT @@ -177,38 +185,82 @@ SURF ---- .. ocv:class:: SURF -Class for extracting Speeded Up Robust Features from an image. :: +Class for extracting Speeded Up Robust Features from an image [Bay06]_. The class is derived from ``CvSURFParams`` structure, which specifies the algorithm parameters: - class SURF : public CvSURFParams - { - public: - // c:function::default constructor - SURF(); - // constructor that initializes all the algorithm parameters - SURF(double _hessianThreshold, int _nOctaves=4, - int _nOctaveLayers=2, bool _extended=false); - // returns the number of elements in each descriptor (64 or 128) - int descriptorSize() const; - // detects keypoints using fast multi-scale Hessian detector - void operator()(const Mat& img, const Mat& mask, - vector& keypoints) const; - // detects keypoints and computes the SURF descriptors for them; - // output vector "descriptors" stores elements of descriptors and has size - // equal descriptorSize()*keypoints.size() as each descriptor is - // descriptorSize() elements of this vector. - void operator()(const Mat& img, const Mat& mask, - vector& keypoints, - vector& descriptors, - bool useProvidedKeypoints=false) const; - }; - -The class implements the Speeded Up Robust Features descriptor -[Bay06]. -There is a fast multi-scale Hessian keypoint detector that can be used to find keypoints -(default option). But the descriptors can be also computed for the user-specified keypoints. -The algorithm can be used for object tracking and localization, image stitching, and so on. See the ``find_obj.cpp`` demo in the OpenCV samples directory. + .. ocv:member:: int extended + + * 0 means that the basic descriptors (64 elements each) shall be computed + * 1 means that the extended descriptors (128 elements each) shall be computed + + .. ocv:member:: int upright + + * 0 means that detector computes orientation of each feature. + * 1 means that the orientation is not computed (which is much, much faster). For example, if you match images from a stereo pair, or do image stitching, the matched features likely have very similar angles, and you can speed up feature extraction by setting ``upright=1``. + + .. ocv:member:: double hessianThreshold + + Threshold for the keypoint detector. Only features, whose hessian is larger than ``hessianThreshold`` are retained by the detector. Therefore, the larger the value, the less keypoints you will get. A good default value could be from 300 to 500, depending from the image contrast. + + .. ocv:member:: int nOctaves + + The number of a gaussian pyramid octaves that the detector uses. It is set to 4 by default. If you want to get very large features, use the larger value. If you want just small features, decrease it. + + .. ocv:member:: int nOctaveLayers + + The number of images within each octave of a gaussian pyramid. It is set to 2 by default. +.. [Bay06] Bay, H. and Tuytelaars, T. and Van Gool, L. "SURF: Speeded Up Robust Features", 9th European Conference on Computer Vision, 2006 + + +SURF::SURF +---------- +The SURF extractor constructors. + +.. ocv:function:: SURF::SURF() + +.. ocv:function:: SURF::SURF(double hessianThreshold, int nOctaves=4, int nOctaveLayers=2, bool extended=false, bool upright=false) + +.. ocv:pyfunction:: cv2.SURF(_hessianThreshold[, _nOctaves[, _nOctaveLayers[, _extended[, _upright]]]]) -> + + :param hessianThreshold: Threshold for hessian keypoint detector used in SURF. + + :param nOctaves: Number of pyramid octaves the keypoint detector will use. + + :param nOctaveLayers: Number of octave layers within each octave. + + :param extended: Extended descriptor flag (true - use extended 128-element descriptors; false - use 64-element descriptors). + + :param upright: Up-right or rotated features flag (true - do not compute orientation of features; false - compute orientation). + + +SURF::operator() +---------------- +Detects keypoints and computes SURF descriptors for them. + +.. ocv:function:: void SURF::operator()(const Mat& image, const Mat& mask, vector& keypoints) +.. ocv:function:: void SURF::operator()(const Mat& image, const Mat& mask, vector& keypoints, vector& descriptors, bool useProvidedKeypoints=false) + +.. ocv:pyfunction:: cv2.SURF.detect(img, mask) -> keypoints +.. ocv:pyfunction:: cv2.SURF.detect(img, mask[, useProvidedKeypoints]) -> keypoints, descriptors + +.. ocv:cfunction:: void cvExtractSURF( const CvArr* image, const CvArr* mask, CvSeq** keypoints, CvSeq** descriptors, CvMemStorage* storage, CvSURFParams params ) + +.. ocv:pyoldfunction:: cv.ExtractSURF(image, mask, storage, params)-> (keypoints, descriptors) + + :param image: Input 8-bit grayscale image + + :param mask: Optional input mask that marks the regions where we should detect features. + + :param keypoints: The input/output vector of keypoints + + :param descriptors: The output concatenated vectors of descriptors. Each descriptor is 64- or 128-element vector, as returned by ``SURF::descriptorSize()``. So the total size of ``descriptors`` will be ``keypoints.size()*descriptorSize()``. + + :param useProvidedKeypoints: Boolean flag. If it is true, the keypoint detector is not run. Instead, the provided vector of keypoints is used and the algorithm just computes their descriptors. + + :param storage: Memory storage for the output keypoints and descriptors in OpenCV 1.x API. + + :param params: SURF algorithm parameters in OpenCV 1.x API. ORB diff --git a/modules/features2d/src/orb.cpp b/modules/features2d/src/orb.cpp index b3d13b9562..d28b20c1b7 100644 --- a/modules/features2d/src/orb.cpp +++ b/modules/features2d/src/orb.cpp @@ -398,6 +398,8 @@ private: //switch (sz) { //default: + if( rotated_patterns_.empty() ) + rotated_patterns_ = OrbPatterns::generateRotatedPatterns(); pattern_data = reinterpret_cast (rotated_patterns_[angle_idx].data); //break; } @@ -437,7 +439,7 @@ private: }; -std::vector ORB::OrbPatterns::rotated_patterns_ = OrbPatterns::generateRotatedPatterns(); +std::vector ORB::OrbPatterns::rotated_patterns_; //this is the definition for BIT_PATTERN #include "orb_pattern.hpp" diff --git a/modules/gpu/doc/camera_calibration_and_3d_reconstruction.rst b/modules/gpu/doc/camera_calibration_and_3d_reconstruction.rst index eea023bfe2..5007e2c2d0 100644 --- a/modules/gpu/doc/camera_calibration_and_3d_reconstruction.rst +++ b/modules/gpu/doc/camera_calibration_and_3d_reconstruction.rst @@ -144,23 +144,24 @@ Class computing stereo correspondence using the belief propagation algorithm. :: ... }; -The class implements Pedro F. Felzenszwalb algorithm [Pedro F. Felzenszwalb and Daniel P. Huttenlocher. *Efficient belief propagation for early vision*. International Journal of Computer Vision, 70(1), October 2006]. It can compute own data cost (using a truncated linear model) or use a user-provided data cost. +The class implements algorithm described in [Felzenszwalb2006]_ . It can compute own data cost (using a truncated linear model) or use a user-provided data cost. .. note:: - ``StereoBeliefPropagation`` requires a lot of memory for message storage: + ``StereoBeliefPropagation`` requires a lot of memory for message storage: - .. math:: + .. math:: - width \_ step \cdot height \cdot ndisp \cdot 4 \cdot (1 + 0.25) + width \_ step \cdot height \cdot ndisp \cdot 4 \cdot (1 + 0.25) - and for data cost storage: + and for data cost storage: - .. math:: + .. math:: - width\_step \cdot height \cdot ndisp \cdot (1 + 0.25 + 0.0625 + \dotsm + \frac{1}{4^{levels}}) + width\_step \cdot height \cdot ndisp \cdot (1 + 0.25 + 0.0625 + \dotsm + \frac{1}{4^{levels}}) + + ``width_step`` is the number of bytes in a line including padding. - ``width_step`` is the number of bytes in a line including padding. .. index:: gpu::StereoBeliefPropagation::StereoBeliefPropagation @@ -198,7 +199,7 @@ gpu::StereoBeliefPropagation::StereoBeliefPropagation DiscTerm = \min (disc \_ single \_ jump \cdot \lvert f_1-f_2 \rvert , max \_ disc \_ term) -For more details, see [Pedro F. Felzenszwalb and Daniel P. Huttenlocher. *Efficient belief propagation for early vision*. International Journal of Computer Vision, 70(1), October 2006]. +For more details, see [Felzenszwalb2006]_. By default, :ocv:class:`StereoBeliefPropagation` uses floating-point arithmetics and the ``CV_32FC1`` type for messages. But it can also use fixed-point arithmetics and the ``CV_16SC1`` message type for better performance. To avoid an overflow in this case, the parameters must satisfy the following requirement: @@ -300,7 +301,7 @@ Class computing stereo correspondence using the constant space belief propagatio }; -The class implements Q. Yang algorithm [Q. Yang, L. Wang, and N. Ahuja. *A constant-space belief propagation algorithm for stereo matching*. In CVPR, 2010]. ``StereoConstantSpaceBP`` supports both local minimum and global minimum data cost initialization algortihms. For more details, see the paper mentioned above. By default, a local algorithm is used. To enable a global algorithm, set ``use_local_init_data_cost`` to ``false``. +The class implements algorithm described in [Yang2010]_. ``StereoConstantSpaceBP`` supports both local minimum and global minimum data cost initialization algortihms. For more details, see the paper mentioned above. By default, a local algorithm is used. To enable a global algorithm, set ``use_local_init_data_cost`` to ``false``. .. index:: gpu::StereoConstantSpaceBP::StereoConstantSpaceBP @@ -342,7 +343,7 @@ gpu::StereoConstantSpaceBP::StereoConstantSpaceBP DiscTerm = \min (disc \_ single \_ jump \cdot \lvert f_1-f_2 \rvert , max \_ disc \_ term) -For more details, see [Q. Yang, L. Wang, and N. Ahuja. *A constant-space belief propagation algorithm for stereo matching*. In CVPR, 2010]. +For more details, see [Yang2010]_. By default, ``StereoConstantSpaceBP`` uses floating-point arithmetics and the ``CV_32FC1`` type for messages. But it can also use fixed-point arithmetics and the ``CV_16SC1`` message type for better perfomance. To avoid an overflow in this case, the parameters must satisfy the following requirement: @@ -410,7 +411,7 @@ Class refinining a disparity map using joint bilateral filtering. :: }; -The class implements Q. Yang algorithm [Q. Yang, L. Wang, and N. Ahuja. *A constant-space belief propagation algorithm for stereo matching*. In CVPR, 2010]. +The class implements [Yang2010]_ algorithm. .. index:: gpu::DisparityBilateralFilter::DisparityBilateralFilter @@ -524,4 +525,8 @@ gpu::solvePnPRansac :param inliers: Output vector of inlier indices. See Also :ocv:func:`solvePnPRansac`. - \ No newline at end of file + + +.. [Felzenszwalb2006] Pedro F. Felzenszwalb algorithm [Pedro F. Felzenszwalb and Daniel P. Huttenlocher. *Efficient belief propagation for early vision*. International Journal of Computer Vision, 70(1), October 2006 + +.. [Yang2010] Q. Yang, L. Wang, and N. Ahuja. *A constant-space belief propagation algorithm for stereo matching*. In CVPR, 2010. diff --git a/modules/gpu/doc/object_detection.rst b/modules/gpu/doc/object_detection.rst index 69ee39faaf..e935beac2d 100644 --- a/modules/gpu/doc/object_detection.rst +++ b/modules/gpu/doc/object_detection.rst @@ -9,7 +9,7 @@ gpu::HOGDescriptor ------------------ .. ocv:class:: gpu::HOGDescriptor -Class providing a histogram of Oriented Gradients [Navneet Dalal and Bill Triggs. *Histogram of oriented gradients for human detection*. 2005.] descriptor and detector. +The class implements Histogram of Oriented Gradients ([Dalal2005]_) object detector. :: struct CV_EXPORTS HOGDescriptor @@ -326,3 +326,4 @@ gpu::CascadeClassifier_GPU::detectMultiScale .. seealso:: :ocv:func:`CascadeClassifier::detectMultiScale` +.. [Dalal2005] Navneet Dalal and Bill Triggs. *Histogram of oriented gradients for human detection*. 2005. diff --git a/modules/highgui/doc/reading_and_writing_images_and_video.rst b/modules/highgui/doc/reading_and_writing_images_and_video.rst index b2a1774edc..1af534ae1e 100644 --- a/modules/highgui/doc/reading_and_writing_images_and_video.rst +++ b/modules/highgui/doc/reading_and_writing_images_and_video.rst @@ -124,58 +124,10 @@ VideoCapture ------------ .. ocv:class:: VideoCapture -Class for video capturing from video files or cameras :: +Class for video capturing from video files or cameras. +The class provides C++ API for capturing video from cameras or for reading video files. Here is how the class can be used: :: - class VideoCapture - { - public: - // the default constructor - VideoCapture(); - // the constructor that opens video file - VideoCapture(const string& filename); - // the constructor that starts streaming from the camera - VideoCapture(int device); - - // the destructor - virtual ~VideoCapture(); - - // opens the specified video file - virtual bool open(const string& filename); - - // starts streaming from the specified camera by its id - virtual bool open(int device); - - // returns true if the file was open successfully or if the camera - // has been initialized succesfully - virtual bool isOpened() const; - - // closes the camera stream or the video file - // (automatically called by the destructor) - virtual void release(); - - // grab the next frame or a set of frames from a multi-head camera; - // returns false if there are no more frames - virtual bool grab(); - // reads the frame from the specified video stream - // (non-zero channel is only valid for multi-head camera live streams) - virtual bool retrieve(Mat& image, int channel=0); - // equivalent to grab() + retrieve(image, 0); - virtual VideoCapture& operator >> (Mat& image); - - // sets the specified property propId to the specified value - virtual bool set(int propId, double value); - // retrieves value of the specified property - virtual double get(int propId); - - protected: - ... - }; - - -The class provides C++ video capturing API. Here is how the class can be used: :: - - #include "cv.h" - #include "highgui.h" + #include "opencv2/opencv.hpp" using namespace cv; @@ -202,6 +154,9 @@ The class provides C++ video capturing API. Here is how the class can be used: : } +.. note:: In C API the black-box structure ``CvCapture`` is used instead of ``VideoCapture``. + + VideoCapture::VideoCapture ------------------------------ VideoCapture constructors. @@ -212,20 +167,131 @@ VideoCapture constructors. .. ocv:function:: VideoCapture::VideoCapture(int device) +.. ocv:pyfunction:: cv2.VideoCapture() -> +.. ocv:pyfunction:: cv2.VideoCapture(filename) -> +.. ocv:pyfunction:: cv2.VideoCapture(device) -> + +.. ocv:cfunction:: CvCapture* cvCaptureFromCAM( int device ) +.. ocv:pyoldfunction:: cv.CaptureFromCAM(device) -> CvCapture +.. ocv:cfunction:: CvCapture* cvCaptureFromFile( const char* filename ) +.. ocv:pyoldfunction:: cv.CaptureFromFile(filename) -> CvCapture + + :param filename: name of the opened video file + + :param device: id of the opened video capturing device (i.e. a camera index). If there is a single camera connected, just pass 0. + +.. note:: In C API, when you finished working with video, release ``CvCapture`` structure with ``cvReleaseCapture()``, or use ``Ptr`` that calls ``cvReleaseCapture()`` automatically in the destructor. + + +VideoCapture::open +--------------------- +Open video file or a capturing device for video capturing + +.. ocv:function:: bool VideoCapture::open(const string& filename) +.. ocv:function:: bool VideoCapture::open(int device) + +.. ocv:pyfunction:: cv2.VideoCapture.open(filename) -> successFlag +.. ocv:pyfunction:: cv2.VideoCapture.open(device) -> successFlag + :param filename: name of the opened video file :param device: id of the opened video capturing device (i.e. a camera index). +The methods first call :ocv:cfunc:`VideoCapture::release` to close the already opened file or camera. + + +VideoCapture::isOpened +---------------------- +Returns true if video capturing has been initialized already. + +.. ocv:function:: bool VideoCapture::isOpened() + +.. ocv:pyfunction:: cv2.VideoCapture.isOpened() -> flag + +If the previous call to ``VideoCapture`` constructor or ``VideoCapture::open`` succeeded, the method returns true. + +VideoCapture::release +--------------------- +Closes video file or capturing device. + +.. ocv:function:: void VideoCapture::release() + +.. ocv:pyfunction:: cv2.VideoCapture.release() + +.. ocv:cfunction: void cvReleaseCapture(CvCapture** capture) + +The methods are automatically called by subsequent :ocv:func:`VideoCapture::open` and by ``VideoCapture`` destructor. + +The C function also deallocates memory and clears ``*capture`` pointer. + + +VideoCapture::grab +--------------------- +Grabs the next frame from video file or capturing device. + +.. ocv:function:: bool VideoCapture::grab() + +.. ocv:pyfunction:: cv2.VideoCapture.grab() -> successFlag + +.. ocv:cfunction: int cvGrabFrame(CvCapture* capture) + +.. ocv:pyoldfunction:: cv.GrabFrame(capture) -> int + +The methods/functions grab the next frame from video file or camera and return true (non-zero) in the case of success. + +The primary use of the function is in multi-camera environments, especially when the cameras do not have hardware synchronization. That is, you call ``VideoCapture::grab()`` for each camera and after that call the slower method ``VideoCapture::retrieve()`` to decode and get frame from each camera. This way the overhead on demosaicing or motion jpeg decompression etc. is eliminated and the retrieved frames from different cameras will be closer in time. + +Also, when a connected camera is multi-head (for example, a stereo camera or a Kinect device), the correct way of retrieving data from it is to call `VideoCapture::grab` first and then call :ocv:func:`VideoCapture::retrieve` one or more times with different values of the ``channel`` parameter. See https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/kinect_maps.cpp + + +VideoCapture::retrieve +---------------------- +Decodes and returns the grabbed video frame. + +.. ocv:function:: bool VideoCapture::retrieve(Mat& image, int channel=0) + +.. ocv:pyfunction:: cv2.VideoCapture.retrieve([image[, channel]]) -> successFlag, image + +.. ocv:cfunction: IplImage* cvRetrieveFrame(CvCapture* capture) + +.. ocv:pyoldfunction:: cv.RetrieveFrame(capture) -> iplimage + +The methods/functions decode and retruen the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer. + +.. note:: OpenCV 1.x functions ``cvRetrieveFrame`` and ``cv.RetrieveFrame`` return image stored inside the video capturing structure. It is not allowed to modify or release the image! You can copy the frame using :ocv:cfunc:`cvCloneImage` and then do whatever you want with the copy. + + +VideoCapture::read +---------------------- +Grabs, decodes and returns the next video frame. + +.. ocv:function:: VideoCapture& VideoCapture::operator >> (Mat& image) +.. ocv:function:: bool VideoCapture::read(Mat& image) + +.. ocv:pyfunction:: cv2.VideoCapture.read([image]) -> successFlag, image + +.. ocv:cfunction: IplImage* cvQueryFrame(CvCapture* capture) + +.. ocv:pyoldfunction:: cv.QueryFrame(capture) -> iplimage + +The methods/functions combine :ocv:func:`VideoCapture::grab` and :ocv:func:`VideoCapture::retrieve` in one call. This is the most convenient method for reading video files or capturing data from decode and retruen the just grabbed frame. If no frames has been grabbed (camera has been disconnected, or there are no more frames in video file), the methods return false and the functions return NULL pointer. + +.. note:: OpenCV 1.x functions ``cvRetrieveFrame`` and ``cv.RetrieveFrame`` return image stored inside the video capturing structure. It is not allowed to modify or release the image! You can copy the frame using :ocv:cfunc:`cvCloneImage` and then do whatever you want with the copy. + VideoCapture::get --------------------- Returns the specified ``VideoCapture`` property -.. ocv:function:: double VideoCapture::get(int property_id) +.. ocv:function:: double VideoCapture::get(int propId) .. ocv:pyfunction:: cv2.VideoCapture.get(propId) -> retval - :param property_id: Property identifier. It can be one of the following: +.. ocv:cfunction:: double cvGetCaptureProperty( CvCapture* capture, int propId ) +.. ocv:pyoldfunction:: cv.GetCaptureProperty(capture, propId)->double + + + :param propId: Property identifier. It can be one of the following: * **CV_CAP_PROP_POS_MSEC** Current position of the video file in milliseconds or video capture timestamp. @@ -272,11 +338,14 @@ VideoCapture::set --------------------- Sets a property in the ``VideoCapture``. -.. ocv:function:: bool VideoCapture::set(int property_id, double value) +.. ocv:function:: bool VideoCapture::set(int propertyId, double value) .. ocv:pyfunction:: cv2.VideoCapture.set(propId, value) -> retval - :param property_id: Property identifier. It can be one of the following: +.. ocv:cfunction:: int cvSetCaptureProperty( CvCapture* capture, int propId, double value ) +.. ocv:pyoldfunction:: cv.SetCaptureProperty(capture, propId, value)->None + + :param propId: Property identifier. It can be one of the following: * **CV_CAP_PROP_POS_MSEC** Current position of the video file in milliseconds. @@ -318,43 +387,90 @@ Sets a property in the ``VideoCapture``. :param value: Value of the property. + + VideoWriter ----------- .. ocv:class:: VideoWriter -Video writer class. :: +Video writer class. - class VideoWriter - { - public: - // default constructor - VideoWriter(); - // constructor that calls open - VideoWriter(const string& filename, int fourcc, - double fps, Size frameSize, bool isColor=true); - // the destructor - virtual ~VideoWriter(); - // opens the file and initializes the video writer. - // filename - the output file name. - // fourcc - the codec - // fps - the number of frames per second - // frameSize - the video frame size - // isColor - specifies whether the video stream is color or grayscale - virtual bool open(const string& filename, int fourcc, - double fps, Size frameSize, bool isColor=true); +VideoWriter::VideoWriter +------------------------ +VideoWriter constructors - // returns true if the writer has been initialized successfully - virtual bool isOpened() const; +.. ocv:function:: VideoWriter::VideoWriter() +.. ocv:function:: VideoWriter::VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true) - // writes the next video frame to the stream - virtual VideoWriter& operator << (const Mat& image); +.. ocv:pyfunction:: cv2.VideoWriter([filename, fourcc, fps, frameSize[, isColor]]) -> - protected: - ... - }; +.. ocv:cfunction:: CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, double fps, CvSize frameSize, int isColor=1 ) +.. ocv:pyoldfunction:: cv.CreateVideoWriter(filename, fourcc, fps, frameSize, isColor) -> CvVideoWriter -For more detailed description see http://opencv.willowgarage.com/wiki/documentation/cpp/highgui/VideoWriter -.. +.. ocv:pyfunction:: cv2.VideoWriter.isOpened() -> retval +.. ocv:pyfunction:: cv2.VideoWriter.open(filename, fourcc, fps, frameSize[, isColor]) -> retval +.. ocv:pyfunction:: cv2.VideoWriter.write(image) -> None + + :param filename: Name of the output video file. + + :param fourcc: 4-character code of codec used to compress the frames. For example, ``CV_FOURCC('P','I','M,'1')`` is a MPEG-1 codec, ``CV_FOURCC('M','J','P','G')`` is a motion-jpeg codec etc. + + :param fps: Framerate of the created video stream. + + :param frameSize: Size of the video frames. + + :param isColor: If it is not zero, the encoder will expect and encode color frames, otherwise it will work with grayscale frames (the flag is currently supported on Windows only). + +The constructors/functions initialize video writers. On Linux FFMPEG is used to write videos; on Windows FFMPEG or VFW is used; on MacOSX QTKit is used. + + + +ReleaseVideoWriter +------------------ +Releases the AVI writer. + +.. ocv:cfunction:: void cvReleaseVideoWriter( CvVideoWriter** writer ) + +The function should be called after you finished using ``CvVideoWriter`` opened with :ocv:cfunc:`CreateVideoWriter`. + + +VideoWriter::open +----------------- +Initializes or reinitializes video writer. + +.. ocv:function: bool VideoWriter::open(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true) + +.. ocv:pyfunction:: cv2.VideoWriter.open(filename, fourcc, fps, frameSize[, isColor]) -> retval + +The method opens video writer. Parameters are the same as in the constructor :ocv:func:`VideoWriter::VideoWriter`. + + +VideoWriter::isOpened +--------------------- +Returns true if video writer has been successfully initialized. + +.. ocv:function: bool VideoWriter::isOpened() + +.. ocv:pyfunction:: cv2.VideoWriter.isOpened() -> retval + + +VideoWriter::write +------------------ +Writes the next video frame + +.. ocv:function:: VideoWriter& VideoWriter::operator << (const Mat& image) +.. ocv:function:: void VideoWriter::write(const Mat& image) + +.. ocv:pyfunction:: cv2.VideoWriter.write(image) -> None + +.. ocv:cfunction:: int cvWriteFrame( CvVideoWriter* writer, const IplImage* image ) +.. ocv:pyoldfunction:: cv.WriteFrame(writer, image)->int + + :param writer: Video writer structure (OpenCV 1.x API) + + :param image: The written frame + +The functions/methods write the specified image to video file. It must have the same size as has been specified when opening the video writer. diff --git a/modules/highgui/doc/user_interface.rst b/modules/highgui/doc/user_interface.rst index 4f8250e0cd..1fc919f546 100644 --- a/modules/highgui/doc/user_interface.rst +++ b/modules/highgui/doc/user_interface.rst @@ -110,6 +110,7 @@ You can call :ocv:func:`destroyWindow` or :ocv:func:`destroyAllWindows` to close By default, ``flags == CV_WINDOW_AUTOSIZE | CV_WINDOW_KEEPRATIO | CV_GUI_EXPANDED`` + destroyWindow ------------- Destroys a window. @@ -134,9 +135,60 @@ Destroys all of the HighGUI windows. .. ocv:pyfunction:: cv2.destroyAllWindows() -> None +.. ocv:cfunction:: void cvDestroyAllWindows() +.. ocv:pyoldfunction:: cv.DestroyAllWindows()-> None + The function ``destroyAllWindows`` destroys all of the opened HighGUI windows. +MoveWindow +---------- +Moves window to the specified position + +.. ocv:cfunction:: void cvMoveWindow( const char* name, int x, int y ) +.. ocv:pyoldfunction:: cv.MoveWindow(name, x, y)-> None + + :param name: Window name + + :param x: The new x-coordinate of the window + + :param y: The new y-coordinate of the window + + +ResizeWindow +---------- +Resizes window to the specified size + +.. ocv:cfunction:: void cvResizeWindow( const char* name, int width, int height ) +.. ocv:pyoldfunction:: cv.ResizeWindow(name, width, height)-> None + + :param name: Window name + + :param width: The new window width + + :param height: The new window height + +.. note:: + + * The specified window size is for the image area. Toolbars are not counted. + + * Only windows created without CV_WINDOW_AUTOSIZE flag can be resized. + + +SetMouseCallback +---------------- +Sets mouse handler for the specified window + +.. ocv:cfunction:: void cvSetMouseCallback( const char* name, CvMouseCallback onMouse, void* param=NULL ) +.. ocv:pyoldfunction:: cv.SetMouseCallback(name, onMouse, param) -> None + + :param name: Window name + + :param onMouse: Mouse callback. See OpenCV samples, such as https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/ffilldemo.cpp, on how to specify and use the callback. + + :param param: The optional parameter passed to the callback. + + setTrackbarPos ------------------ Sets the trackbar position. diff --git a/modules/imgproc/doc/feature_detection.rst b/modules/imgproc/doc/feature_detection.rst index cda7d6b60c..d1ef5b95c6 100644 --- a/modules/imgproc/doc/feature_detection.rst +++ b/modules/imgproc/doc/feature_detection.rst @@ -7,7 +7,7 @@ Feature Detection Canny --------- -Finds edges in an image using the Canny algorithm. +Finds edges in an image using the [Canny86]_ algorithm. .. ocv:function:: void Canny( InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize=3, bool L2gradient=false ) @@ -242,7 +242,7 @@ Determines strong corners on an image. :param k: Free parameter of the Harris detector. -The function finds the most prominent corners in the image or in the specified image region, as described in [Shi94]: +The function finds the most prominent corners in the image or in the specified image region, as described in [Shi94]_: #. Function calculates the corner quality measure at every source image pixel using the @@ -287,7 +287,7 @@ Finds circles in a grayscale image using the Hough transform. :param circles: Output vector of found circles. Each vector is encoded as a 3-element floating-point vector :math:`(x, y, radius)` . - :param method: The detection method to use. Currently, the only implemented method is ``CV_HOUGH_GRADIENT`` , which is basically *21HT* , described in [Yuen90]. + :param method: The detection method to use. Currently, the only implemented method is ``CV_HOUGH_GRADIENT`` , which is basically *21HT* , described in [Yuen90]_. :param dp: Inverse ratio of the accumulator resolution to the image resolution. For example, if ``dp=1`` , the accumulator has the same resolution as the input image. If ``dp=2`` , the accumulator has half as big width and height. @@ -420,8 +420,7 @@ Finds line segments in a binary image using the probabilistic Hough transform. :param maxLineGap: Maximum allowed gap between points on the same line to link them. The function implements the probabilistic Hough transform algorithm for line detection, described in -Matas00 -. See the line detection example below: :: +[Matas00]_. See the line detection example below: :: /* This is a standalone program. Pass an image name as a first parameter of the program. Switch between standard and probabilistic Hough transform @@ -524,4 +523,10 @@ The corners can be found as local maximums of the functions, as shown below: :: dilate(corners, dilated_corners, Mat(), 1); Mat corner_mask = corners == dilated_corners; +.. [Canny86] J. Canny. A Computational Approach to Edge Detection, IEEE Trans. on Pattern Analysis and Machine Intelligence, 8(6), pp. 679-698 (1986). +.. [Matas00] Matas, J. and Galambos, C. and Kittler, J.V., “Robust Detection of Lines Using the Progressive Probabilistic Hough Transform”. CVIU 78 1, pp 119-137 (2000) + +.. [Shi94] J. Shi and C. Tomasi. Good features to track. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition, pages 593-600, June 1994. + +.. [Yuen90] Yuen, H. K. and Princen, J. and Illingworth, J. and Kittler, J., “Comparative study of Hough transform methods for circle finding”. Image Vision Comput. 8 1, pp 71–77 (1990) \ No newline at end of file diff --git a/modules/imgproc/doc/filtering.rst b/modules/imgproc/doc/filtering.rst index d1003986df..6f0e69aa10 100644 --- a/modules/imgproc/doc/filtering.rst +++ b/modules/imgproc/doc/filtering.rst @@ -1044,10 +1044,14 @@ getStructuringElement ------------------------- Returns a structuring element of the specified size and shape for morphological operations. -.. ocv:function:: Mat getStructuringElement(int shape, Size esize, Point anchor=Point(-1,-1)) +.. ocv:function:: Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1)) .. ocv:pyfunction:: cv2.getStructuringElement(shape, ksize[, anchor]) -> retval +.. ocv:cfunction:: IplConvKernel* cvCreateStructuringElementEx( int cols, int rows, int anchorX, int anchorY, int shape, int* values=NULL ) + +.. ocv:pyoldfunction:: cv.CreateStructuringElementEx(cols, rows, anchorX, anchorY, shape, values=None)-> kernel + :param shape: Element shape that could be one of the following: * **MORPH_RECT** - a rectangular structuring element: @@ -1063,10 +1067,22 @@ Returns a structuring element of the specified size and shape for morphological .. math:: E_{ij} = \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise} + + * **CV_SHAPE_CUSTOM** - custom structuring element (OpenCV 1.x API) - :param esize: Size of the structuring element. + :param ksize: Size of the structuring element. + + :param cols: Width of the structuring element + + :param rows: Height of the structuring element :param anchor: Anchor position within the element. The default value :math:`(-1, -1)` means that the anchor is at the center. Note that only the shape of a cross-shaped element depends on the anchor position. In other cases the anchor just regulates how much the result of the morphological operation is shifted. + + :param anchorX: x-coordinate of the anchor + + :param anchorY: y-coordinate of the anchor + + :param values: integer array of ``cols``*``rows`` elements that specifies the custom shape of the structuring element, when ``shape=CV_SHAPE_CUSTOM``. The function constructs and returns the structuring element that can be further passed to :ocv:func:`createMorphologyFilter`, @@ -1074,6 +1090,7 @@ The function constructs and returns the structuring element that can be further :ocv:func:`dilate` or :ocv:func:`morphologyEx` . But you can also construct an arbitrary binary mask yourself and use it as the structuring element. +.. note:: When using OpenCV 1.x C API, the created structuring element ``IplConvKernel* element`` must be released in the end using ``cvReleaseStructuringElement(&element)``. medianBlur @@ -1277,6 +1294,54 @@ The function performs the upsampling step of the Gaussian pyramid construction :ocv:func:`pyrDown` multiplied by 4. +pyrMeanShiftFiltering +--------------------- +Performs initial step of meanshift segmentation of an image. + +.. ocv:function: void pyrMeanShiftFiltering( InputArray src, OutputArray dst, double sp, double sr, int maxLevel=1, TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) ) + +.. ocv:pyfunction:: cv2.pyrMeanShiftFiltering(src, sp, sr[, dst[, maxLevel[, termcrit]]]) -> dst + +.. ocv:cfunction:: void cvPyrMeanShiftFiltering( const CvArr* src, CvArr* dst, double sp, double sr, int max_level=1, CvTermCriteria termcrit= cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,5,1)) + +.. ocv:pyoldfunction:: cv.PyrMeanShiftFiltering(src, dst, sp, sr, maxLevel=1, termcrit=(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 5, 1))-> None + + :param src: The source 8-bit, 3-channel image. + + :param dst: The destination image of the same format and the same size as the source. + + :param sp: The spatial window radius. + + :param sr: The color window radius. + + :param maxLevel: Maximum level of the pyramid for the segmentation. + + :param termcrit: Termination criteria: when to stop meanshift iterations. + + +The function implements the filtering stage of meanshift segmentation, that is, the output of the function is the filtered "posterized" image with color gradients and fine-grain texture flattened. At every pixel +``(X,Y)`` of the input image (or down-sized input image, see below) the function executes meanshift +iterations, that is, the pixel ``(X,Y)`` neighborhood in the joint space-color hyperspace is considered: + + .. math:: + + (x,y): X- \texttt{sp} \le x \le X+ \texttt{sp} , Y- \texttt{sp} \le y \le Y+ \texttt{sp} , ||(R,G,B)-(r,g,b)|| \le \texttt{sr} + + +where ``(R,G,B)`` and ``(r,g,b)`` are the vectors of color components at ``(X,Y)`` and ``(x,y)``, respectively (though, the algorithm does not depend on the color space used, so any 3-component color space can be used instead). Over the neighborhood the average spatial value ``(X',Y')`` and average color vector ``(R',G',B')`` are found and they act as the neighborhood center on the next iteration: + + .. math:: + + (X,Y)~(X',Y'), (R,G,B)~(R',G',B'). + +After the iterations over, the color components of the initial pixel (that is, the pixel from where the iterations started) are set to the final value (average color at the last iteration): + + .. math:: + + I(X,Y) <- (R*,G*,B*) + +When ``maxLevel > 0``, the gaussian pyramid of ``maxLevel+1`` levels is built, and the above procedure is run on the smallest layer first. After that, the results are propagated to the larger layer and the iterations are run again only on those pixels where the layer colors differ by more than ``sr`` from the lower-resolution layer of the pyramid. That makes boundaries of color regions sharper. Note that the results will be actually different from the ones obtained by running the meanshift procedure on the whole original image (i.e. when ``maxLevel==0``). + sepFilter2D --------------- @@ -1313,6 +1378,57 @@ The function applies a separable linear filter to the image. That is, first, eve :ocv:func:`blur` +Smooth +------ +Smooths the image in one of several ways. + +.. ocv:cfunction:: void cvSmooth( const CvArr* src, CvArr* dst, int smoothtype=CV_GAUSSIAN, int param1=3, int param2=0, double param3=0, double param4=0) + +.. ocv:pyoldfunction:: cv.Smooth(src, dst, smoothtype=CV_GAUSSIAN, param1=3, param2=0, param3=0, param4=0)-> None + + :param src: The source image + + :param dst: The destination image + + :param smoothtype: Type of the smoothing: + + * **CV_BLUR_NO_SCALE** linear convolution with :math:`\texttt{param1}\times\texttt{param2}` box kernel (all 1's). If you want to smooth different pixels with different-size box kernels, you can use the integral image that is computed using :ref:`Integral` + + + * **CV_BLUR** linear convolution with :math:`\texttt{param1}\times\texttt{param2}` box kernel (all 1's) with subsequent scaling by :math:`1/(\texttt{param1}\cdot\texttt{param2})` + + + * **CV_GAUSSIAN** linear convolution with a :math:`\texttt{param1}\times\texttt{param2}` Gaussian kernel + + + * **CV_MEDIAN** median filter with a :math:`\texttt{param1}\times\texttt{param1}` square aperture + + + * **CV_BILATERAL** bilateral filter with a :math:`\texttt{param1}\times\texttt{param1}` square aperture, color sigma= ``param3`` and spatial sigma= ``param4`` . If ``param1=0`` , the aperture square side is set to ``cvRound(param4*1.5)*2+1`` . Information about bilateral filtering can be found at http://www.dai.ed.ac.uk/CVonline/LOCAL\_COPIES/MANDUCHI1/Bilateral\_Filtering.html + + + :param param1: The first parameter of the smoothing operation, the aperture width. Must be a positive odd number (1, 3, 5, ...) + + :param param2: The second parameter of the smoothing operation, the aperture height. Ignored by ``CV_MEDIAN`` and ``CV_BILATERAL`` methods. In the case of simple scaled/non-scaled and Gaussian blur if ``param2`` is zero, it is set to ``param1`` . Otherwise it must be a positive odd number. + + :param param3: In the case of a Gaussian parameter this parameter may specify Gaussian :math:`\sigma` (standard deviation). If it is zero, it is calculated from the kernel size: + + .. math:: + + \sigma = 0.3 (n/2 - 1) + 0.8 \quad \text{where} \quad n= \begin{array}{l l} \mbox{\texttt{param1} for horizontal kernel} \\ \mbox{\texttt{param2} for vertical kernel} \end{array} + + Using standard sigma for small kernels ( :math:`3\times 3` to :math:`7\times 7` ) gives better speed. If ``param3`` is not zero, while ``param1`` and ``param2`` are zeros, the kernel size is calculated from the sigma (to provide accurate enough operation). + +The function smooths an image using one of several methods. Every of the methods has some features and restrictions listed below: + + * Blur with no scaling works with single-channel images only and supports accumulation of 8-bit to 16-bit format (similar to :ocv:func:`Sobel` and :ocv:func:`Laplace`) and 32-bit floating point to 32-bit floating-point format. + + * Simple blur and Gaussian blur support 1- or 3-channel, 8-bit and 32-bit floating point images. These two methods can process images in-place. + + * Median and bilateral filters work with 1- or 3-channel 8-bit images and can not process images in-place. + +.. note:: The function is now obsolete. Use :ocv:func:`GaussianBlur`, :ocv:func:`blur`, :ocv:func:`medianBlur` or :ocv:func:`bilateralFilter`. + Sobel --------- diff --git a/modules/imgproc/doc/geometric_transformations.rst b/modules/imgproc/doc/geometric_transformations.rst index 1abf014adc..b87e504b09 100644 --- a/modules/imgproc/doc/geometric_transformations.rst +++ b/modules/imgproc/doc/geometric_transformations.rst @@ -191,6 +191,8 @@ Calculates an affine matrix of 2D rotation. .. ocv:pyfunction:: cv2.getRotationMatrix2D(center, angle, scale) -> retval +.. ocv:cfunction:: CvMat* cv2DRotationMatrix( CvPoint2D32f center, double angle, double scale, CvMat* mapMatrix ) + .. ocv:pyoldfunction:: cv.GetRotationMatrix2D(center, angle, scale, mapMatrix)-> None :param center: Center of the rotation in the source image. @@ -199,6 +201,8 @@ Calculates an affine matrix of 2D rotation. :param scale: Isotropic scale factor. + :param mapMatrix: The output affine transformation, 2x3 floating-point matrix. + The function calculates the following matrix: .. math:: @@ -246,6 +250,53 @@ The result is also a +LogPolar +-------- +Remaps an image to log-polar space. + +.. ocv:cfunction:: void cvLogPolar( const CvArr* src, CvArr* dst, CvPoint2D32f center, double M, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ) + +.. ocv:pyoldfunction:: cv.LogPolar(src, dst, center, M, flags=CV_INNER_LINEAR+CV_WARP_FILL_OUTLIERS)-> None + + :param src: Source image + + :param dst: Destination image + + :param center: The transformation center; where the output precision is maximal + + :param M: Magnitude scale parameter. See below + + :param flags: A combination of interpolation methods and the following optional flags: + + * **CV_WARP_FILL_OUTLIERS** fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero + + + * **CV_WARP_INVERSE_MAP** See below + +The function ``cvLogPolar`` transforms the source image using the following transformation: + + * Forward transformation (``CV_WARP_INVERSE_MAP``is not set): + + .. math:: + + dst( \phi , \rho ) = src(x,y) + + + * Inverse transformation (``CV_WARP_INVERSE_MAP`` is set): + + .. math:: + + dst(x,y) = src( \phi , \rho ) + + +where + + .. math:: + + \rho = M \cdot \log{\sqrt{x^2 + y^2}} , \phi =atan(y/x) + + +The function emulates the human "foveal" vision and can be used for fast scale and rotation-invariant template matching, for object tracking and so forth. The function can not operate in-place. remap @@ -376,6 +427,9 @@ Applies an affine transformation to an image. .. ocv:cfunction:: void cvWarpAffine( const CvArr* src, CvArr* dst, const CvMat* mapMatrix, int flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, CvScalar fillval=cvScalarAll(0) ) .. ocv:pyoldfunction:: cv.WarpAffine(src, dst, mapMatrix, flags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, fillval=(0, 0, 0, 0))-> None +.. ocv:cfunction:: void cvGetQuadrangleSubPix( const CvArr* src, CvArr* dst, const CvMat* mapMatrix ) +.. ocv:pyoldfunction:: cv.GetQuadrangleSubPix(src, dst, mapMatrix)-> None + :param src: Source image. :param dst: Destination image that has the size ``dsize`` and the same type as ``src`` . @@ -408,6 +462,7 @@ See Also: :ocv:func:`transform` +.. note:: ``cvGetQuadrangleSubPix`` is similar to ``cvWarpAffine``, but the outliers are extrapolated using replication border mode. warpPerspective ------------------- @@ -464,13 +519,16 @@ Computes the undistortion and rectification transformation map. .. ocv:pyfunction:: cv2.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size, m1type[, map1[, map2]]) -> map1, map2 .. ocv:cfunction:: void cvInitUndistortRectifyMap( const CvMat* cameraMatrix, const CvMat* distCoeffs, const CvMat* R, const CvMat* newCameraMatrix, CvArr* map1, CvArr* map2 ) +.. ocv:cfunction:: void cvInitUndistortMap( const CvMat* cameraMatrix, const CvMat* distCoeffs, CvArr* map1, CvArr* map2 ) + .. ocv:pyoldfunction:: cv.InitUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, map1, map2)-> None +.. ocv:pyoldfunction:: cv.InitUndistortMap(cameraMatrix, distCoeffs, map1, map2)-> None :param cameraMatrix: Input camera matrix :math:`A=\vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` . :param distCoeffs: Input vector of distortion coefficients :math:`(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6]])` of 4, 5, or 8 elements. If the vector is NULL/empty, the zero distortion coefficients are assumed. - :param R: Optional rectification transformation in the object space (3x3 matrix). ``R1`` or ``R2`` , computed by :ref:`StereoRectify` can be passed here. If the matrix is empty, the identity transformation is assumed. + :param R: Optional rectification transformation in the object space (3x3 matrix). ``R1`` or ``R2`` , computed by :ref:`StereoRectify` can be passed here. If the matrix is empty, the identity transformation is assumed. In ``cvInitUndistortMap`` R assumed to be an identity matrix. :param newCameraMatrix: New camera matrix :math:`A'=\vecthreethree{f_x'}{0}{c_x'}{0}{f_y'}{c_y'}{0}{0}{1}` . @@ -574,8 +632,8 @@ Transforms an image to compensate for lens distortion. The function transforms an image to compensate radial and tangential lens distortion. The function is simply a combination of -:ref:`InitUndistortRectifyMap` (with unity ``R`` ) and -:ref:`Remap` (with bilinear interpolation). See the former function for details of the transformation being performed. +:ocv:func:`initUndistortRectifyMap` (with unity ``R`` ) and +:ocv:func:`remap` (with bilinear interpolation). See the former function for details of the transformation being performed. Those pixels in the destination image, for which there is no correspondent pixels in the source image, are filled with zeros (black color). diff --git a/modules/imgproc/doc/histograms.rst b/modules/imgproc/doc/histograms.rst index 9593875b05..c1fe52fe8b 100644 --- a/modules/imgproc/doc/histograms.rst +++ b/modules/imgproc/doc/histograms.rst @@ -250,9 +250,7 @@ Computes the "minimal work" distance between two weighted point configurations. :param userdata: Optional pointer directly passed to the custom distance function. -The function computes the earth mover distance and/or a lower boundary of the distance between the two weighted point configurations. One of the applications described in :ref:`RubnerSept98` is multi-dimensional histogram comparison for image retrieval. EMD is a transportation problem that is solved using some modification of a simplex algorithm, thus the complexity is exponential in the worst case, though, on average it is much faster. In the case of a real metric the lower boundary can be calculated even faster (using linear-time algorithm) and it can be used to determine roughly whether the two signatures are far enough so that they cannot relate to the same object. - - +The function computes the earth mover distance and/or a lower boundary of the distance between the two weighted point configurations. One of the applications described in [RubnerSept98]_ is multi-dimensional histogram comparison for image retrieval. EMD is a transportation problem that is solved using some modification of a simplex algorithm, thus the complexity is exponential in the worst case, though, on average it is much faster. In the case of a real metric the lower boundary can be calculated even faster (using linear-time algorithm) and it can be used to determine roughly whether the two signatures are far enough so that they cannot relate to the same object. equalizeHist @@ -263,6 +261,8 @@ Equalizes the histogram of a grayscale image. .. ocv:pyfunction:: cv2.equalizeHist(src[, dst]) -> dst +.. ocv:cfunction:: void cvEqualizeHist( const CvArr* src, CvArr* dst ) + :param src: Source 8-bit single channel image. :param dst: Destination image of the same size and type as ``src`` . @@ -289,3 +289,296 @@ The function equalizes the histogram of the input image using the following algo :math:`\texttt{dst}(x,y) = H'(\texttt{src}(x,y))` The algorithm normalizes the brightness and increases the contrast of the image. + + +Extra Histogram Functions (C API) +--------------------------------- + +In the rest of the section additional C functions operating on ``CvHistogram`` are described. + +CalcBackProjectPatch +-------------------- +Locates a template within an image by using a histogram comparison. + +.. ocv:cfunction:: void cvCalcBackProjectPatch( IplImage** images, CvArr* dst, CvSize patch_size, CvHistogram* hist, int method, double factor ) + +.. ocv:pyoldfunction:: cv.CalcBackProjectPatch(images, dst, patchSize, hist, method, factor)-> None + + :param images: Source images (though, you may pass CvMat** as well) + + :param dst: Destination image + + :param patch_size: Size of the patch slid though the source image + + :param hist: Histogram + + :param method: Comparison method, passed to :ref:`CompareHist` (see description of that function) + + :param factor: Normalization factor for histograms, will affect the normalization scale of the destination image, pass 1 if unsure + +The function calculates the back projection by comparing histograms of the source image patches with the given histogram. The function is similar to :ocv:func:`MatchTemplate`, but instead of comparing raster patch with all its possible positions within the search window, the function ``CalcBackProjectPatch`` compares histograms. Below is the diagram of the algorithm: :: + +.. image:: pics/backprojectpatch.png + + +CalcProbDensity +--------------- +Divides one histogram by another. + +.. ocv:cfunction:: void cvCalcProbDensity( const CvHistogram* hist1, const CvHistogram* hist2, CvHistogram* dsthist, double scale=255 ) + +.. ocv:pyoldfunction:: cv.CalcProbDensity(hist1, hist2, dsthist, scale=255)-> None + + :param hist1: first histogram (the divisor) + + :param hist2: second histogram + + :param dsthist: destination histogram + + :param scale: scale factor for the destination histogram + +The function calculates the object probability density from the two histograms as: + +.. math:: + + \texttt{disthist} (I)= \forkthree{0}{if $\texttt{hist1}(I)=0$}{\texttt{scale}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) > \texttt{hist1}(I)$}{\frac{\texttt{hist2}(I) \cdot \texttt{scale}}{\texttt{hist1}(I)}}{if $\texttt{hist1}(I) \ne 0$ and $\texttt{hist2}(I) \le \texttt{hist1}(I)$} + + +ClearHist +--------- +Clears the histogram. + +.. ocv:cfunction:: void cvClearHist( CvHistogram* hist ) +.. ocv:pyoldfunction:: cv.ClearHist(hist)-> None + + :param hist: Histogram + +The function sets all of the histogram bins to 0 in the case of a dense histogram and removes all histogram bins in the case of a sparse array. + + +CopyHist +-------- +Copies a histogram. + +.. ocv:cfunction:: void cvCopyHist( const CvHistogram* src, CvHistogram** dst ) + + :param src: Source histogram + + :param dst: Pointer to destination histogram + +The function makes a copy of the histogram. If the second histogram pointer ``*dst`` is NULL, a new histogram of the same size as ``src`` is created. Otherwise, both histograms must have equal types and sizes. Then the function copies the source histogram's bin values to the destination histogram and sets the same bin value ranges as in ``src``. + + +CreateHist +---------- +Creates a histogram. + +.. ocv:cfunction:: CvHistogram* cvCreateHist( int dims, int* sizes, int type, float** ranges=NULL, int uniform=1 ) + +.. ocv:pyoldfunction:: cv.CreateHist(dims, type, ranges, uniform=1) -> hist + + :param dims: Number of histogram dimensions + + :param sizes: Array of the histogram dimension sizes + + :param type: Histogram representation format: ``CV_HIST_ARRAY`` means that the histogram data is represented as a multi-dimensional dense array CvMatND; ``CV_HIST_SPARSE`` means that histogram data is represented as a multi-dimensional sparse array CvSparseMat + + :param ranges: Array of ranges for the histogram bins. Its meaning depends on the ``uniform`` parameter value. The ranges are used for when the histogram is calculated or backprojected to determine which histogram bin corresponds to which value/tuple of values from the input image(s) + + :param uniform: Uniformity flag; if not 0, the histogram has evenly + spaced bins and for every :math:`0<=ibins, (idx0), 0 )) + #define cvGetHistValue_2D( hist, idx0, idx1 ) + ((float*)(cvPtr2D( (hist)->bins, (idx0), (idx1), 0 ))) + #define cvGetHistValue_3D( hist, idx0, idx1, idx2 ) + ((float*)(cvPtr3D( (hist)->bins, (idx0), (idx1), (idx2), 0 ))) + #define cvGetHistValue_nD( hist, idx ) + ((float*)(cvPtrND( (hist)->bins, (idx), 0 ))) + +.. + +The macros ``GetHistValue`` return a pointer to the specified bin of the 1D, 2D, 3D or N-D histogram. In the case of a sparse histogram the function creates a new bin and sets it to 0, unless it exists already. + + +GetMinMaxHistValue +------------------ +Finds the minimum and maximum histogram bins. + +.. ocv:cfunction:: void cvGetMinMaxHistValue( const CvHistogram* hist, float* min_value, float* max_value, int* min_idx=NULL, int* max_idx=NULL ) + +.. ocv:pyoldfunction:: cv.GetMinMaxHistValue(hist)-> (minValue, maxValue, minIdx, maxIdx) + + :param hist: Histogram + + :param min_value: Pointer to the minimum value of the histogram + + :param max_value: Pointer to the maximum value of the histogram + + :param min_idx: Pointer to the array of coordinates for the minimum + + :param max_idx: Pointer to the array of coordinates for the maximum + +The function finds the minimum and maximum histogram bins and their positions. All of output arguments are optional. Among several extremas with the same value the ones with the minimum index (in lexicographical order) are returned. In the case of several maximums or minimums, the earliest in lexicographical order (extrema locations) is returned. + + +MakeHistHeaderForArray +---------------------- +Makes a histogram out of an array. + +.. ocv:cfunction:: CvHistogram* cvMakeHistHeaderForArray( int dims, int* sizes, CvHistogram* hist, float* data, float** ranges=NULL, int uniform=1 ) + + :param dims: Number of histogram dimensions + + :param sizes: Array of the histogram dimension sizes + + :param hist: The histogram header initialized by the function + + :param data: Array that will be used to store histogram bins + + :param ranges: Histogram bin ranges, see :ref:`CreateHist` + + :param uniform: Uniformity flag, see :ref:`CreateHist` + +The function initializes the histogram, whose header and bins are allocated by the user. :ocv:cfunc:`ReleaseHist` does not need to be called afterwards. Only dense histograms can be initialized this way. The function returns ``hist``. + +NormalizeHist +------------- +Normalizes the histogram. + +.. ocv:cfunction:: void cvNormalizeHist( CvHistogram* hist, double factor ) +.. ocv:pyoldfunction:: cv.NormalizeHist(hist, factor)-> None + + :param hist: Pointer to the histogram + + :param factor: Normalization factor + +The function normalizes the histogram bins by scaling them, such that the sum of the bins becomes equal to ``factor``. + + +QueryHistValue*D +---------------- +Queries the value of the histogram bin. + +.. ocv:cfunction:: float QueryHistValue_1D(CvHistogram hist, int idx0) +.. ocv:cfunction:: float QueryHistValue_2D(CvHistogram hist, int idx0, int idx1) +.. ocv:cfunction:: float QueryHistValue_3D(CvHistogram hist, int idx0, int idx1, int idx2) +.. ocv:cfunction:: float QueryHistValue_nD(CvHistogram hist, const int* idx) + +.. ocv:pyoldfunction:: cv.QueryHistValue_1D(hist, idx0) -> float +.. ocv:pyoldfunction:: cv.QueryHistValue_2D(hist, idx0, idx1) -> float +.. ocv:pyoldfunction:: cv.QueryHistValue_3D(hist, idx0, idx1, idx2) -> float +.. ocv:pyoldfunction:: cv.QueryHistValueND(hist, idx) -> float + + :param hist: Histogram + + :param idx0, idx1, idx2, idx3: Indices of the bin + + :param idx: Array of indices + +The macros return the value of the specified bin of the 1D, 2D, 3D or N-D histogram. In the case of a sparse histogram the function returns 0, if the bin is not present in the histogram no new bin is created. + +ReleaseHist +----------- +Releases the histogram. + +.. ocv:cfunction:: void cvReleaseHist( CvHistogram** hist ) + + :param hist: Double pointer to the released histogram + +The function releases the histogram (header and the data). The pointer to the histogram is cleared by the function. If ``*hist`` pointer is already ``NULL``, the function does nothing. + + +SetHistBinRanges +---------------- +Sets the bounds of the histogram bins. + +.. ocv:cfunction:: void cvSetHistBinRanges( CvHistogram* hist, float** ranges, int uniform=1 ) + + :param hist: Histogram + + :param ranges: Array of bin ranges arrays, see :ref:`CreateHist` + + :param uniform: Uniformity flag, see :ref:`CreateHist` + +The function is a stand-alone function for setting bin ranges in the histogram. For a more detailed description of the parameters ``ranges`` and ``uniform`` see the :ocv:cfunc:`CalcHist` function, that can initialize the ranges as well. Ranges for the histogram bins must be set before the histogram is calculated or the backproject of the histogram is calculated. + + +ThreshHist +---------- +Thresholds the histogram. + +.. ocv:cfunction:: void cvThreshHist( CvHistogram* hist, double threshold ) +.. ocv:pyoldfunction:: cv.ThreshHist(hist, threshold)-> None + + :param hist: Pointer to the histogram + + :param threshold: Threshold level + +The function clears histogram bins that are below the specified threshold. + + +CalcPGH +------- +Calculates a pair-wise geometrical histogram for a contour. + +.. ocv:cfunction:: void cvCalcPGH( const CvSeq* contour, CvHistogram* hist ) +.. ocv:pyoldfunction:: cv.CalcPGH(contour, hist)-> None + + :param contour: Input contour. Currently, only integer point coordinates are allowed + + :param hist: Calculated histogram; must be two-dimensional + +The function calculates a 2D pair-wise geometrical histogram (PGH), described in [Iivarinen97]_ for the contour. The algorithm considers every pair of contour +edges. The angle between the edges and the minimum/maximum distances +are determined for every pair. To do this each of the edges in turn +is taken as the base, while the function loops through all the other +edges. When the base edge and any other edge are considered, the minimum +and maximum distances from the points on the non-base edge and line of +the base edge are selected. The angle between the edges defines the row +of the histogram in which all the bins that correspond to the distance +between the calculated minimum and maximum distances are incremented +(that is, the histogram is transposed relatively to the definition in the original paper). The histogram can be used for contour matching. + +.. [RubnerSept98] Y. Rubner. C. Tomasi, L.J. Guibas. The Earth Mover’s Distance as a Metric for Image Retrieval. Technical Report STAN-CS-TN-98-86, Department of Computer Science, Stanford University, September 1998. + +.. [Iivarinen97] Jukka Iivarinen, Markus Peura, Jaakko Srel, and Ari Visa. Comparison of Combined Shape Descriptors for Irregular Objects, 8th British Machine Vision Conference, BMVC'97. +http://www.cis.hut.fi/research/IA/paper/publications/bmvc97/bmvc97.html \ No newline at end of file diff --git a/modules/imgproc/doc/miscellaneous_transformations.rst b/modules/imgproc/doc/miscellaneous_transformations.rst index e8572efa53..fdf0fc0e02 100644 --- a/modules/imgproc/doc/miscellaneous_transformations.rst +++ b/modules/imgproc/doc/miscellaneous_transformations.rst @@ -421,7 +421,9 @@ Calculates the distance to the closest zero pixel for each pixel of the source i :param src: 8-bit, single-channel (binary) source image. :param dst: Output image with calculated distances. It is a 32-bit floating-point, single-channel image of the same size as ``src`` . + :param distanceType: Type of distance. It can be ``CV_DIST_L1, CV_DIST_L2`` , or ``CV_DIST_C`` . + :param maskSize: Size of the distance transform mask. It can be 3, 5, or ``CV_DIST_MASK_PRECISE`` (the latter option is only supported by the first function). In case of the ``CV_DIST_L1`` or ``CV_DIST_C`` distance type, the parameter is forced to 3 because a :math:`3\times 3` mask gives the same result as :math:`5\times 5` or any larger aperture. :param labels: Optional output 2D array of labels (the discrete Voronoi diagram). It has the type ``CV_32SC1`` and the same size as ``src`` . See the details below. @@ -430,11 +432,10 @@ The functions ``distanceTransform`` calculate the approximate or precise distance from every binary image pixel to the nearest zero pixel. For zero image pixels, the distance will obviously be zero. -When ``maskSize == CV_DIST_MASK_PRECISE`` and ``distanceType == CV_DIST_L2`` , the function runs the algorithm described in -Felzenszwalb04. +When ``maskSize == CV_DIST_MASK_PRECISE`` and ``distanceType == CV_DIST_L2`` , the function runs the algorithm described in [Felzenszwalb04]_. In other cases, the algorithm -Borgefors86 +[Borgefors86]_ is used. This means that for a pixel the function finds the shortest path to the nearest zero pixel consisting of basic shifts: horizontal, @@ -608,7 +609,7 @@ Restores the selected region in an image using the region neighborhood. * **INPAINT_NS** Navier-Stokes based method. - * **INPAINT_TELEA** Method by Alexandru Telea Telea04. + * **INPAINT_TELEA** Method by Alexandru Telea [Telea04]_. The function reconstructs the selected image area from the pixel near the area boundary. The function may be used to remove dust and scratches from a scanned photo, or to remove undesirable objects from still images or video. See http://en.wikipedia.org/wiki/Inpainting @@ -765,7 +766,7 @@ Performs a marker-based image segmentation using the watershed algrorithm. The function implements one of the variants of watershed, non-parametric marker-based segmentation algorithm, -described in [Meyer92]. Before passing the image to the +described in [Meyer92]_. Before passing the image to the function, you have to roughly outline the desired regions in the image ``markers`` with positive ( :math:`>0` ) indices. So, every region is represented as one or more connected components with the pixel values @@ -827,3 +828,11 @@ Runs the GrabCut algorithm. The function implements the `GrabCut image segmentation algorithm `_. See the sample grabcut.cpp to learn how to use the function. + +.. [Borgefors86] Borgefors, Gunilla, “Distance transformations in digital images”. Comput. Vision Graph. Image Process. 34 3, pp 344–371 (1986) + +.. [Felzenszwalb04] Felzenszwalb, Pedro F. and Huttenlocher, Daniel P. “Distance Transforms of Sampled Functions”, TR2004-1963, TR2004-1963 (2004) + +.. [Meyer92] Meyer, F. “Color image segmentation”, ICIP92, 1992 + +.. [Telea04] Alexandru Telea, “An Image Inpainting Technique Based on the Fast Marching Method”. Journal of Graphics, GPU, and Game Tools 9 1, pp 23-34 (2004) diff --git a/doc/opencv1/c/imgproc_planar_subdivisions.rst b/modules/imgproc/doc/planar_subdivisions.rst similarity index 64% rename from doc/opencv1/c/imgproc_planar_subdivisions.rst rename to modules/imgproc/doc/planar_subdivisions.rst index e4b29aa98d..a5085cee9f 100644 --- a/doc/opencv1/c/imgproc_planar_subdivisions.rst +++ b/modules/imgproc/doc/planar_subdivisions.rst @@ -1,32 +1,17 @@ -Planar Subdivisions -=================== +Planar Subdivisions (C API) +============================ .. highlight:: c - - -.. index:: CvSubdiv2D - -.. _CvSubdiv2D: - CvSubdiv2D ---------- - - -.. ctype:: CvSubdiv2D - - +.. ocv:struct:: CvSubdiv2D Planar subdivision. - - - :: - - #define CV_SUBDIV2D_FIELDS() \ CV_GRAPH_FIELDS() \ int quad_edges; \ @@ -40,7 +25,6 @@ Planar subdivision. CV_SUBDIV2D_FIELDS() } CvSubdiv2D; - .. @@ -58,11 +42,7 @@ the original subdivision vertices become facets. On the picture below original subdivision is marked with solid lines and dual subdivision with dotted lines. - - -.. image:: ../pics/subdiv.png - - +.. image:: pics/subdiv.png OpenCV subdivides a plane into triangles using Delaunay's algorithm. Subdivision is built iteratively starting from a dummy @@ -72,29 +52,15 @@ subdivisions can be used for the 3d piece-wise transformation of a plane, morphing, fast location of points on the plane, building special graphs (such as NNG,RNG) and so forth. - -.. index:: CvQuadEdge2D - -.. _CvQuadEdge2D: - CvQuadEdge2D ------------ - - -.. ctype:: CvQuadEdge2D - - +.. ocv:struct:: CvQuadEdge2D Quad-edge of planar subdivision. - - - :: - - /* one of edges within quad-edge, lower 2 bits is index (0..3) and upper bits are quad-edge pointer */ typedef long CvSubdiv2DEdge; @@ -110,42 +76,22 @@ Quad-edge of planar subdivision. CV_QUADEDGE2D_FIELDS() } CvQuadEdge2D; - - .. Quad-edge is a basic element of subdivision containing four edges (e, eRot, reversed e and reversed eRot): - - -.. image:: ../pics/quadedge.png - - - - -.. index:: CvSubdiv2DPoint - -.. _CvSubdiv2DPoint: +.. image:: pics/quadedge.png CvSubdiv2DPoint --------------- - - -.. ctype:: CvSubdiv2DPoint - - +.. ocv:struct:: CvSubdiv2DPoint Point of original or dual subdivision. - - - :: - - #define CV_SUBDIV2D_POINT_FIELDS()\ int flags; \ CvSubdiv2DEdge first; \ @@ -159,111 +105,53 @@ Point of original or dual subdivision. CV_SUBDIV2D_POINT_FIELDS() } CvSubdiv2DPoint; - .. - - - - * id This integer can be used to index auxillary data associated with each vertex of the planar subdivision - - - -.. index:: CalcSubdivVoronoi2D - -.. _CalcSubdivVoronoi2D: CalcSubdivVoronoi2D ------------------- +Calculates the coordinates of Voronoi diagram cells. +.. ocv:cfunction:: void cvCalcSubdivVoronoi2D( CvSubdiv2D* subdiv ) +.. ocv:pyoldfunction:: cv.CalcSubdivVoronoi2D(subdiv)-> None + :param subdiv: Delaunay subdivision, in which all the points are already added - - - -.. cfunction:: void cvCalcSubdivVoronoi2D( CvSubdiv2D* subdiv ) - - Calculates the coordinates of Voronoi diagram cells. - - - - - - - :param subdiv: Delaunay subdivision, in which all the points are already added - - - The function calculates the coordinates of virtual points. All virtual points corresponding to some vertex of the original subdivision form (when connected together) a boundary of the Voronoi cell at that point. - -.. index:: ClearSubdivVoronoi2D - -.. _ClearSubdivVoronoi2D: - ClearSubdivVoronoi2D -------------------- - - - - - -.. cfunction:: void cvClearSubdivVoronoi2D( CvSubdiv2D* subdiv ) +.. ocv:cfunction:: void cvClearSubdivVoronoi2D( CvSubdiv2D* subdiv ) +.. ocv:pyoldfunction:: cv.ClearSubdivVoronoi2D(subdiv)-> None Removes all virtual points. + :param subdiv: Delaunay subdivision - - - - - :param subdiv: Delaunay subdivision - - - The function removes all of the virtual points. It is called internally in :ref:`CalcSubdivVoronoi2D` if the subdivision was modified after previous call to the function. - - -.. index:: CreateSubdivDelaunay2D - -.. _CreateSubdivDelaunay2D: - CreateSubdivDelaunay2D ---------------------- +Creates an empty Delaunay triangulation. +.. ocv:cfunction:: CvSubdiv2D* cvCreateSubdivDelaunay2D( CvRect rect, CvMemStorage* storage ) +.. ocv:pyoldfunction:: cv.CreateSubdivDelaunay2D(rect, storage)-> emptyDelaunayTriangulation + :param rect: Rectangle that includes all of the 2d points that are to be added to the subdivision + :param storage: Container for subdivision - - -.. cfunction:: CvSubdiv2D* cvCreateSubdivDelaunay2D( CvRect rect, CvMemStorage* storage ) - - Creates an empty Delaunay triangulation. - - - - - - - :param rect: Rectangle that includes all of the 2d points that are to be added to the subdivision - - - :param storage: Container for subdivision - - - The function creates an empty Delaunay subdivision, where 2d points can be added using the function :ref:`SubdivDelaunay2DInsert` @@ -274,35 +162,17 @@ Note that the triangulation is a single large triangle that covers the given rec ``rect`` . - -.. index:: FindNearestPoint2D - -.. _FindNearestPoint2D: - FindNearestPoint2D ------------------ +Finds the closest subdivision vertex to the given point. +.. ocv:cfunction:: CvSubdiv2DPoint* cvFindNearestPoint2D( CvSubdiv2D* subdiv, CvPoint2D32f pt ) +.. ocv:pyoldfunction:: cv.FindNearestPoint2D(subdiv, pt)-> point + :param subdiv: Delaunay or another subdivision + :param pt: Input point - - -.. cfunction:: CvSubdiv2DPoint* cvFindNearestPoint2D( CvSubdiv2D* subdiv, CvPoint2D32f pt ) - - Finds the closest subdivision vertex to the given point. - - - - - - - :param subdiv: Delaunay or another subdivision - - - :param pt: Input point - - - The function is another function that locates the input point within the subdivision. It finds the subdivision vertex that is the closest to the input point. It is not necessarily one of vertices @@ -311,32 +181,15 @@ of the facet containing the input point, though the facet (located using ) is used as a starting point. The function returns a pointer to the found subdivision vertex. - -.. index:: Subdiv2DEdgeDst - -.. _Subdiv2DEdgeDst: - Subdiv2DEdgeDst --------------- +Returns the edge destination. +.. ocv:cfunction:: CvSubdiv2DPoint* cvSubdiv2DEdgeDst( CvSubdiv2DEdge edge ) +.. ocv:pyoldfunction:: cv.Subdiv2DEdgeDst(edge)-> point + :param edge: Subdivision edge (not a quad-edge) - - - -.. cfunction:: CvSubdiv2DPoint* cvSubdiv2DEdgeDst( CvSubdiv2DEdge edge ) - - Returns the edge destination. - - - - - - - :param edge: Subdivision edge (not a quad-edge) - - - The function returns the edge destination. The returned pointer may be NULL if the edge is from dual subdivision and the virtual point coordinates are not calculated yet. The virtual points @@ -344,158 +197,77 @@ can be calculated using the function :ref:`CalcSubdivVoronoi2D` . - -.. index:: Subdiv2DGetEdge - -.. _Subdiv2DGetEdge: - Subdiv2DGetEdge --------------- +Returns one of the edges related to the given edge. +.. ocv:cfunction:: CvSubdiv2DEdge cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type ) +.. ocv:pyoldfunction:: cv.Subdiv2DGetEdge(edge, type)-> CvSubdiv2DEdge + :param edge: Subdivision edge (not a quad-edge) + :param type: Specifies which of the related edges to return, one of the following: + * **CV_NEXT_AROUND_ORG** next around the edge origin ( ``eOnext`` on the picture below if ``e`` is the input edge) + * **CV_NEXT_AROUND_DST** next around the edge vertex ( ``eDnext`` ) -.. cfunction:: CvSubdiv2DEdge cvSubdiv2DGetEdge( CvSubdiv2DEdge edge, CvNextEdgeType type ) + * **CV_PREV_AROUND_ORG** previous around the edge origin (reversed ``eRnext`` ) - Returns one of the edges related to the given edge. + * **CV_PREV_AROUND_DST** previous around the edge destination (reversed ``eLnext`` ) + * **CV_NEXT_AROUND_LEFT** next around the left facet ( ``eLnext`` ) + * **CV_NEXT_AROUND_RIGHT** next around the right facet ( ``eRnext`` ) + * **CV_PREV_AROUND_LEFT** previous around the left facet (reversed ``eOnext`` ) - - - :param edge: Subdivision edge (not a quad-edge) - - - :param type: Specifies which of the related edges to return, one of the following: - - - - - * **CV_NEXT_AROUND_ORG** next around the edge origin ( ``eOnext`` on the picture below if ``e`` is the input edge) - - - * **CV_NEXT_AROUND_DST** next around the edge vertex ( ``eDnext`` ) - - - * **CV_PREV_AROUND_ORG** previous around the edge origin (reversed ``eRnext`` ) - - - * **CV_PREV_AROUND_DST** previous around the edge destination (reversed ``eLnext`` ) - - - * **CV_NEXT_AROUND_LEFT** next around the left facet ( ``eLnext`` ) - - - * **CV_NEXT_AROUND_RIGHT** next around the right facet ( ``eRnext`` ) - - - * **CV_PREV_AROUND_LEFT** previous around the left facet (reversed ``eOnext`` ) - - - * **CV_PREV_AROUND_RIGHT** previous around the right facet (reversed ``eDnext`` ) - - - - - - + * **CV_PREV_AROUND_RIGHT** previous around the right facet (reversed ``eDnext`` ) .. image:: ../pics/quadedge.png - - The function returns one of the edges related to the input edge. - -.. index:: Subdiv2DNextEdge - -.. _Subdiv2DNextEdge: - Subdiv2DNextEdge ---------------- +Returns next edge around the edge origin +.. ocv:cfunction:: CvSubdiv2DEdge cvSubdiv2DNextEdge( CvSubdiv2DEdge edge ) +.. ocv:pyoldfunction:: cv.Subdiv2DNextEdge(edge)-> CvSubdiv2DEdge - - - - -.. cfunction:: CvSubdiv2DEdge cvSubdiv2DNextEdge( CvSubdiv2DEdge edge ) - - Returns next edge around the edge origin - - - - - - - :param edge: Subdivision edge (not a quad-edge) - - - - + :param edge: Subdivision edge (not a quad-edge) .. image:: ../pics/quadedge.png - - The function returns the next edge around the edge origin: ``eOnext`` on the picture above if ``e`` is the input edge) - -.. index:: Subdiv2DLocate - -.. _Subdiv2DLocate: - Subdiv2DLocate -------------- +Returns the location of a point within a Delaunay triangulation. +.. ocv:cfunction:: CvSubdiv2DPointLocation cvSubdiv2DLocate( CvSubdiv2D* subdiv, CvPoint2D32f pt, CvSubdiv2DEdge* edge, CvSubdiv2DPoint** vertex=NULL ) +.. ocv:pyoldfunction:: cv.Subdiv2DLocate(subdiv, pt) -> (loc, where) + :param subdiv: Delaunay or another subdivision + :param pt: The point to locate + :param edge: The output edge the point falls onto or right to + :param vertex: Optional output vertex double pointer the input point coinsides with -.. cfunction:: CvSubdiv2DPointLocation cvSubdiv2DLocate( CvSubdiv2D* subdiv, CvPoint2D32f pt, CvSubdiv2DEdge* edge, CvSubdiv2DPoint** vertex=NULL ) - - Returns the location of a point within a Delaunay triangulation. - - - - - - - :param subdiv: Delaunay or another subdivision - - - :param pt: The point to locate - - - :param edge: The output edge the point falls onto or right to - - - :param vertex: Optional output vertex double pointer the input point coinsides with - - - The function locates the input point within the subdivision. There are 5 cases: - - - - * The point falls into some facet. The function returns ``CV_PTLOC_INSIDE`` and ``*edge`` will contain one of edges of the facet. - - * The point falls onto the edge. The function returns @@ -503,8 +275,6 @@ The function locates the input point within the subdivision. There are 5 cases: and ``*edge`` will contain this edge. - - * The point coincides with one of the subdivision vertices. The function returns @@ -512,101 +282,50 @@ The function locates the input point within the subdivision. There are 5 cases: and ``*vertex`` will contain a pointer to the vertex. - - * The point is outside the subdivsion reference rectangle. The function returns ``CV_PTLOC_OUTSIDE_RECT`` and no pointers are filled. - - * One of input arguments is invalid. A runtime error is raised or, if silent or "parent" error processing mode is selected, ``CV_PTLOC_ERROR`` is returnd. - - - -.. index:: Subdiv2DRotateEdge - -.. _Subdiv2DRotateEdge: Subdiv2DRotateEdge ------------------ +Returns another edge of the same quad-edge. +.. ocv:cfunction:: CvSubdiv2DEdge cvSubdiv2DRotateEdge( CvSubdiv2DEdge edge, int rotate ) +.. ocv:pyoldfunction:: cv.Subdiv2DRotateEdge(edge, rotate)-> CvSubdiv2DEdge + :param edge: Subdivision edge (not a quad-edge) + :param rotate: Specifies which of the edges of the same quad-edge as the input one to return, one of the following: + * **0** the input edge ( ``e`` on the picture below if ``e`` is the input edge) + * **1** the rotated edge ( ``eRot`` ) -.. cfunction:: CvSubdiv2DEdge cvSubdiv2DRotateEdge( CvSubdiv2DEdge edge, int rotate ) - - Returns another edge of the same quad-edge. - - - - - - - :param edge: Subdivision edge (not a quad-edge) - - - :param rotate: Specifies which of the edges of the same quad-edge as the input one to return, one of the following: - - - * **0** the input edge ( ``e`` on the picture below if ``e`` is the input edge) - - - * **1** the rotated edge ( ``eRot`` ) - - - * **2** the reversed edge (reversed ``e`` (in green)) - - - * **3** the reversed rotated edge (reversed ``eRot`` (in green)) - - - - - + * **2** the reversed edge (reversed ``e`` (in green)) + * **3** the reversed rotated edge (reversed ``eRot`` (in green)) .. image:: ../pics/quadedge.png - - The function returns one of the edges of the same quad-edge as the input edge. - -.. index:: SubdivDelaunay2DInsert - -.. _SubdivDelaunay2DInsert: - SubdivDelaunay2DInsert ---------------------- +Inserts a single point into a Delaunay triangulation. +.. ocv:cfunction:: CvSubdiv2DPoint* cvSubdivDelaunay2DInsert( CvSubdiv2D* subdiv, CvPoint2D32f pt) +.. ocv:pyoldfunction:: cv.SubdivDelaunay2DInsert(subdiv, pt)-> point + :param subdiv: Delaunay subdivision created by the function :ref:`CreateSubdivDelaunay2D` + :param pt: Inserted point - - -.. cfunction:: CvSubdiv2DPoint* cvSubdivDelaunay2DInsert( CvSubdiv2D* subdiv, CvPoint2D32f pt) - - Inserts a single point into a Delaunay triangulation. - - - - - - - :param subdiv: Delaunay subdivision created by the function :ref:`CreateSubdivDelaunay2D` - - - :param pt: Inserted point - - - The function inserts a single point into a subdivision and modifies the subdivision topology appropriately. If a point with the same coordinates exists already, no new point is added. The function returns a pointer to the allocated point. No virtual point coordinates are calculated at this stage. diff --git a/modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst b/modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst index 5d6757fe01..a3218a68f1 100644 --- a/modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst +++ b/modules/imgproc/doc/structural_analysis_and_shape_descriptors.rst @@ -98,9 +98,8 @@ Calculates the seven Hu invariants. :param moments: Input moments computed with :ocv:func:`moments` . :param h: Output Hu invariants. -The function calculates the seven Hu invariants (see -http://en.wikipedia.org/wiki/Image_moment -) defined as: +The function calculates the seven Hu invariants (introduced in [Hu62]_; see also +http://en.wikipedia.org/wiki/Image_moment) defined as: .. math:: @@ -149,13 +148,12 @@ Finds contours in a binary image. * **CV_CHAIN_APPROX_SIMPLE** compresses horizontal, vertical, and diagonal segments and leaves only their end points. For example, an up-right rectangular contour is encoded with 4 points. - * **CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS** applies one of the flavors of the Teh-Chin chain approximation algorithm. See TehChin89 for details. + * **CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS** applies one of the flavors of the Teh-Chin chain approximation algorithm. See [TehChin89]_ for details. :param offset: Optional offset by which every contour point is shifted. This is useful if the contours are extracted from the image ROI and then they should be analyzed in the whole image context. The function retrieves contours from the binary image using the algorithm -Suzuki85 -. The contours are a useful tool for shape analysis and object detection and recognition. See ``squares.c`` in the OpenCV sample directory. +[Suzuki85]_. The contours are a useful tool for shape analysis and object detection and recognition. See ``squares.c`` in the OpenCV sample directory. **Note**: Source ``image`` is modified by this function. @@ -381,20 +379,55 @@ Finds the convex hull of a point set. .. ocv:pyfunction:: cv2.convexHull(points[, hull[, returnPoints[, clockwise]]]) -> hull +.. ocv:cfunction:: CvSeq* cvConvexHull2( const CvArr* input, void* storage=NULL, int orientation=CV_CLOCKWISE, int returnPoints=0 ) + +.. ocv:pyoldfunction:: cv.ConvexHull2(points, storage, orientation=CV_CLOCKWISE, returnPoints=0)-> convexHull + :param points: Input 2D point set, stored in ``std::vector`` or ``Mat``. :param hull: Output convex hull. It is either an integer vector of indices or vector of points. In the first case the ``hull`` elements are 0-based indices of the convex hull points in the original array (since the set of convex hull points is a subset of the original point set). In the second case ``hull`` elements will be the convex hull points themselves. + + :param storage: The output memory storage in the old API (``cvConvexHull2`` returns a sequence containing the convex hull points or their indices). :param clockwise: Orientation flag. If true, the output convex hull will be oriented clockwise. Otherwise, it will be oriented counter-clockwise. The usual screen coordinate system is assumed where the origin is at the top-left corner, x axis is oriented to the right, and y axis is oriented downwards. + :param orientation: Convex hull orientation parameter in the old API, ``CV_CLOCKWISE`` or ``CV_COUNTERCLOCKWISE``. + :param returnPoints: Operation flag. In the case of matrix, when the flag is true, the function will return convex hull points, otherwise it will return indices of the convex hull points. When the output array is ``std::vector``, the flag is ignored, and the output depends on the type of the vector - ``std::vector`` implies ``returnPoints=true``, ``std::vector`` implies ``returnPoints=false``. The functions find the convex hull of a 2D point set using the Sklansky's algorithm -Sklansky82 +[Sklansky82]_ that has *O(N logN)* complexity in the current implementation. See the OpenCV sample ``convexhull.cpp`` that demonstrates the usage of different function variants. +ConvexityDefects +---------------- +Finds the convexity defects of a contour. + +.. ocv:cfunction:: CvSeq* cvConvexityDefects( const CvArr* contour, const CvArr* convexhull, CvMemStorage* storage=NULL ) + +.. ocv:pyoldfunction:: cv.ConvexityDefects(contour, convexhull, storage)-> convexityDefects + + :param contour: Input contour + + :param convexhull: Convex hull obtained using :ocv:cfunc:`ConvexHull2` that should contain pointers or indices to the contour points, not the hull points themselves (the ``returnPoints`` parameter in :ocv:cfunc:`ConvexHull2` should be 0) + + :param storage: Container for the output sequence of convexity defects. If it is NULL, the contour or hull (in that order) storage is used + +The function finds all convexity defects of the input contour and returns a sequence of the ``CvConvexityDefect`` structures, where ``CvConvexityDetect`` is defined as: :: + + struct CvConvexityDefect + { + CvPoint* start; // point of the contour where the defect begins + CvPoint* end; // point of the contour where the defect ends + CvPoint* depth_point; // the farthest from the convex hull point within the defect + float depth; // distance between the farthest point and the convex hull + }; + +Here is the picture displaying convexity defects of a hand contour: + +.. image:: pics/defects.png fitEllipse -------------- @@ -404,11 +437,18 @@ Fits an ellipse around a set of 2D points. .. ocv:pyfunction:: cv2.fitEllipse(points) -> retval - :param points: Input vector of 2D points, stored in ``std::vector<>`` or ``Mat``. +.. ocv:cfunction:: CvBox2D cvFitEllipse2( const CvArr* points ) +.. ocv:pyoldfunction:: cv.FitEllipse2(points)-> Box2D -The function calculates the ellipse that fits (in least-squares sense) a set of 2D points best of all. It returns the rotated rectangle in which the ellipse is inscribed. + :param points: The input 2D point set, stored in: + + * ``std::vector<>`` or ``Mat`` (C++ interface). + * ``CvSeq*`` or ``CvMat*`` (C interface) + * Nx2 numpy array (Python interface) + +The function calculates the ellipse that fits (in least-squares sense) a set of 2D points best of all. It returns the rotated rectangle in which the ellipse is inscribed. The algorithm [Fitzgibbon95]_ is used. fitLine ----------- @@ -489,7 +529,16 @@ Tests a contour convexity. .. ocv:pyfunction:: cv2.isContourConvex(contour) -> retval - :param contour: The input vector of 2D points, stored in ``std::vector<>`` or ``Mat``. +.. ocv:cfunction:: int cvCheckContourConvexity( const CvArr* contour ) +.. ocv:pyoldfunction:: cv.CheckContourConvexity(contour)-> int + + :param contour: The input vector of 2D points, stored in: + + * ``std::vector<>`` or ``Mat`` (C++ interface). + + * ``CvSeq*`` or ``CvMat*`` (C interface) + + * Nx2 numpy array (Python interface) The function tests whether the input contour is convex or not. The contour must be simple, that is, without self-intersections. Otherwise, the function output is undefined. @@ -631,3 +680,12 @@ Here is a sample output of the function where each image pixel is tested against .. image:: pics/pointpolygon.png +.. [Fitzgibbon95] Andrew W. Fitzgibbon, R.B.Fisher. A Buyer’s Guide to Conic Fitting. Proc.5th British Machine Vision Conference, Birmingham, pp. 513-522, 1995. + +.. [Hu62] M. Hu. Visual Pattern Recognition by Moment Invariants, IRE Transactions on Information Theory, 8:2, pp. 179-187, 1962. + +.. [Sklansky82] Sklansky, J., “Finding the Convex Hull of a Simple Polygon”. PRL 1 $number, pp 79-83 (1982) + +.. [Suzuki85] Suzuki, S. and Abe, K., “Topological Structural Analysis of Digitized Binary Images by Border Following”. CVGIP 30 1, pp 32-46 (1985) + +.. [TehChin89] Teh, C.H. and Chin, R.T., “On the Detection of Dominant Points on Digital Curve”. PAMI 11 8, pp 859-872 (1989) diff --git a/modules/ml/doc/boosting.rst b/modules/ml/doc/boosting.rst index 57653d2f99..11c167ac29 100644 --- a/modules/ml/doc/boosting.rst +++ b/modules/ml/doc/boosting.rst @@ -10,8 +10,7 @@ A common machine learning task is supervised learning. In supervised learning, t :math:`x` and the output :math:`y` . Predicting the qualitative output is called *classification*, while predicting the quantitative output is called *regression*. -Boosting is a powerful learning concept that provides a solution to the supervised classification learning task. It combines the performance of many "weak" classifiers to produce a powerful committee -:ref:`[HTF01] ` . A weak classifier is only required to be better than chance, and thus can be very simple and computationally inexpensive. However, many of them smartly combine results to a strong classifier that often outperforms most "monolithic" strong classifiers such as SVMs and Neural Networks. +Boosting is a powerful learning concept that provides a solution to the supervised classification learning task. It combines the performance of many "weak" classifiers to produce a powerful committee [HTF01]_. A weak classifier is only required to be better than chance, and thus can be very simple and computationally inexpensive. However, many of them smartly combine results to a strong classifier that often outperforms most "monolithic" strong classifiers such as SVMs and Neural Networks. Decision trees are the most popular weak classifiers used in boosting schemes. Often the simplest decision trees with only a single split node per tree (called ``stumps`` ) are sufficient. @@ -23,8 +22,7 @@ The boosted model is based on :math:`x_i` is a :math:`K` -component vector. Each component encodes a feature relevant to the learning task at hand. The desired two-class output is encoded as -1 and +1. -Different variants of boosting are known as Discrete Adaboost, Real AdaBoost, LogitBoost, and Gentle AdaBoost -:ref:`[FHT98] ` . All of them are very similar in their overall structure. Therefore, this chapter focuses only on the standard two-class Discrete AdaBoost algorithm, outlined below. Initially the same weight is assigned to each sample (step 2). Then, a weak classifier +Different variants of boosting are known as Discrete Adaboost, Real AdaBoost, LogitBoost, and Gentle AdaBoost [FHT98]_. All of them are very similar in their overall structure. Therefore, this chapter focuses only on the standard two-class Discrete AdaBoost algorithm, outlined below. Initially the same weight is assigned to each sample (step 2). Then, a weak classifier :math:`f_{m(x)}` is trained on the weighted training data (step 3a). Its weighted training error and scaling factor :math:`c_m` is computed (step 3b). The weights are increased for training samples that have been misclassified (step 3c). All weights are then normalized, and the process of finding the next weak classifier continues for another :math:`M` -1 times. The final classifier @@ -55,20 +53,15 @@ Different variants of boosting are known as Discrete Adaboost, Real AdaBoost, Lo #. Classify new samples *x* using the formula: :math:`\textrm{sign} (\Sigma m = 1M c_m f_m(x))` . -.. note:: Similar to the classical boosting methods, the current implementation supports two-class classifiers only. For M :math:`>` two classes, there is the **AdaBoost.MH** algorithm (described in :ref:`[FHT98] ` ) that reduces the problem to the two-class problem, yet with a much larger training set. +.. note:: Similar to the classical boosting methods, the current implementation supports two-class classifiers only. For ``M > 2`` classes, there is the **AdaBoost.MH** algorithm (described in [FHT98]_) that reduces the problem to the two-class problem, yet with a much larger training set. To reduce computation time for boosted models without substantially losing accuracy, the influence trimming technique can be employed. As the training algorithm proceeds and the number of trees in the ensemble is increased, a larger number of the training samples are classified correctly and with increasing confidence, thereby those samples receive smaller weights on the subsequent iterations. Examples with a very low relative weight have a small impact on the weak classifier training. Thus, such examples may be excluded during the weak classifier training without having much effect on the induced classifier. This process is controlled with the ``weight_trim_rate`` parameter. Only examples with the summary fraction ``weight_trim_rate`` of the total weight mass are used in the weak classifier training. Note that the weights for **all** -training examples are recomputed at each training iteration. Examples deleted at a particular iteration may be used again for learning some of the weak classifiers further -:ref:`[FHT98] ` . +training examples are recomputed at each training iteration. Examples deleted at a particular iteration may be used again for learning some of the weak classifiers further [FHT98]_. -.. _HTF01: +.. [HTF01] Hastie, T., Tibshirani, R., Friedman, J. H. *The Elements of Statistical Learning: Data Mining, Inference, and Prediction*. Springer Series in Statistics. 2001. -[HTF01] Hastie, T., Tibshirani, R., Friedman, J. H. *The Elements of Statistical Learning: Data Mining, Inference, and Prediction*. Springer Series in Statistics. 2001. - -.. _FHT98: - -[FHT98] Friedman, J. H., Hastie, T. and Tibshirani, R. *Additive Logistic Regression: a Statistical View of Boosting*. Technical Report, Dept. of Statistics, Stanford University, 1998. +.. [FHT98] Friedman, J. H., Hastie, T. and Tibshirani, R. *Additive Logistic Regression: a Statistical View of Boosting*. Technical Report, Dept. of Statistics, Stanford University, 1998. CvBoostParams ------------- @@ -151,6 +144,9 @@ Default and training constructors. .. ocv:cfunction:: CvBoost::CvBoost( const CvMat* trainData, int tflag, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, const CvMat* varType=0, const CvMat* missingDataMask=0, CvBoostParams params=CvBoostParams() ) +.. ocv:pyfunction:: cv2.Boost(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params]]]]]) -> + + The constructors follow conventions of :ocv:func:`CvStatModel::CvStatModel`. See :ocv:func:`CvStatModel::train` for parameters descriptions. CvBoost::train @@ -159,7 +155,7 @@ Trains a boosted tree classifier. .. ocv:function:: bool CvBoost::train( const Mat& trainData, int tflag, const Mat& responses, const Mat& varIdx=Mat(), const Mat& sampleIdx=Mat(), const Mat& varType=Mat(), const Mat& missingDataMask=Mat(), CvBoostParams params=CvBoostParams(), bool update=false ) -.. ocv:pyfunction:: cv2.CvBoost.train(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params[, update]]]]]]) -> retval +.. ocv:pyfunction:: cv2.Boost.train(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params[, update]]]]]]) -> retval .. ocv:cfunction:: bool CvBoost::train( const CvMat* trainData, int tflag, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, const CvMat* varType=0, const CvMat* missingDataMask=0, CvBoostParams params=CvBoostParams(), bool update=false ) @@ -177,7 +173,7 @@ Predicts a response for an input sample. .. ocv:cfunction:: float CvBoost::predict( const CvMat* sample, const CvMat* missing=0, CvMat* weak_responses=0, CvSlice slice=CV_WHOLE_SEQ, bool raw_mode=false, bool return_sum=false ) const -.. ocv:pyfunction:: cv2.CvBoost.predict(sample[, missing[, slice[, rawMode[, returnSum]]]]) -> retval +.. ocv:pyfunction:: cv2.Boost.predict(sample[, missing[, slice[, rawMode[, returnSum]]]]) -> retval :param sample: Input sample. @@ -199,7 +195,7 @@ Removes the specified weak classifiers. .. ocv:cfunction:: void CvBoost::prune( CvSlice slice ) -.. ocv:pyfunction:: cv2.CvBoost.prune(slice) -> None +.. ocv:pyfunction:: cv2.Boost.prune(slice) -> None :param slice: Continuous subset of the sequence of weak classifiers to be removed. diff --git a/modules/ml/doc/decision_trees.rst b/modules/ml/doc/decision_trees.rst index ed277dd541..da47f38f29 100644 --- a/modules/ml/doc/decision_trees.rst +++ b/modules/ml/doc/decision_trees.rst @@ -1,8 +1,7 @@ Decision Trees ============== -The ML classes discussed in this section implement Classification and Regression Tree algorithms described in `[Breiman84] <#paper_Breiman84>`_ -. +The ML classes discussed in this section implement Classification and Regression Tree algorithms described in [Breiman84]_. The class :ocv:class:`CvDTree` represents a single decision tree that may be used alone or as a base class in tree ensembles (see @@ -55,7 +54,6 @@ Besides the prediction that is an obvious use of decision trees, the tree can be Importance of each variable is computed over all the splits on this variable in the tree, primary and surrogate ones. Thus, to compute variable importance correctly, the surrogate splits must be enabled in the training parameters, even if there is no missing data. -[Breiman84] Breiman, L., Friedman, J. Olshen, R. and Stone, C. (1984), *Classification and Regression Trees*, Wadsworth. CvDTreeSplit ------------ @@ -235,7 +233,7 @@ Trains a decision tree. .. ocv:cfunction:: bool CvDTree::train( CvDTreeTrainData* trainData, const CvMat* subsampleIdx ) -.. ocv:pyfunction:: cv2.CvDTree.train(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params]]]]]) -> retval +.. ocv:pyfunction:: cv2.DTree.train(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params]]]]]) -> retval There are four ``train`` methods in :ocv:class:`CvDTree`: @@ -255,7 +253,7 @@ Returns the leaf node of a decision tree corresponding to the input vector. .. ocv:cfunction:: CvDTreeNode* CvDTree::predict( const CvMat* sample, const CvMat* missingDataMask=0, bool preprocessedInput=false ) const -.. ocv:pyfunction:: cv2.CvDTree.predict(sample[, missingDataMask[, preprocessedInput]]) -> retval +.. ocv:pyfunction:: cv2.DTree.predict(sample[, missingDataMask[, preprocessedInput]]) -> retval :param sample: Sample for prediction. @@ -294,6 +292,7 @@ Returns the variable importance array. .. ocv:cfunction:: const CvMat* CvDTree::get_var_importance() +.. ocv:pyfunction:: cv2.DTree.getVarImportance() -> importanceVector CvDTree::get_root ----------------- @@ -319,3 +318,6 @@ Returns used train data of the decision tree. Example: building a tree for classifying mushrooms. See the ``mushroom.cpp`` sample that demonstrates how to build and use the decision tree. + +.. [Breiman84] Breiman, L., Friedman, J. Olshen, R. and Stone, C. (1984), *Classification and Regression Trees*, Wadsworth. + diff --git a/modules/ml/doc/expectation_maximization.rst b/modules/ml/doc/expectation_maximization.rst index ed19ca8845..c7e69827ab 100644 --- a/modules/ml/doc/expectation_maximization.rst +++ b/modules/ml/doc/expectation_maximization.rst @@ -157,7 +157,7 @@ Estimates the Gaussian mixture parameters from a sample set. .. ocv:function:: bool CvEM::train( const CvMat* samples, const CvMat* sampleIdx=0, CvEMParams params=CvEMParams(), CvMat* labels=0 ) -.. ocv:pyfunction:: cv2.CvEM.train(samples[, sampleIdx[, params]]) -> retval, labels +.. ocv:pyfunction:: cv2.EM.train(samples[, sampleIdx[, params]]) -> retval, labels :param samples: Samples from which the Gaussian mixture model will be estimated. @@ -189,7 +189,7 @@ Returns a mixture component index of a sample. .. ocv:function:: float CvEM::predict( const CvMat* sample, CvMat* probs ) const -.. ocv:pyfunction:: cv2.CvEM.predict(sample) -> retval, probs +.. ocv:pyfunction:: cv2.EM.predict(sample) -> retval, probs :param sample: A sample for classification. @@ -204,8 +204,10 @@ Returns the number of mixture components :math:`M` in the gaussian mixture model .. ocv:function:: int CvEM::get_nclusters() const +.. ocv:pyfunction:: cv2.EM.getNClusters() -> retval -CvEM::getNClusters + +CvEM::getMeans ------------------ Returns mixture means :math:`a_k`. @@ -213,6 +215,8 @@ Returns mixture means :math:`a_k`. .. ocv:function:: const CvMat* CvEM::get_means() const +.. ocv:pyfunction:: cv2.EM.getMeans() -> means + CvEM::getCovs ------------- @@ -222,6 +226,8 @@ Returns mixture covariance matrices :math:`S_k`. .. ocv:function:: const CvMat** CvEM::get_covs() const +.. ocv:pyfunction:: cv2.EM.getCovs([covs]) -> covs + CvEM::getWeights ---------------- @@ -231,6 +237,8 @@ Returns mixture weights :math:`\pi_k`. .. ocv:function:: const CvMat* CvEM::get_weights() const +.. ocv:pyfunction:: cv2.EM.getWeights() -> weights + CvEM::getProbs -------------- @@ -240,6 +248,8 @@ Returns vectors of probabilities for each training sample. .. ocv:function:: const CvMat* CvEM::get_probs() const +.. ocv:pyfunction:: cv2.EM.getProbs() -> probs + For each training sample :math:`i` (that have been passed to the constructor or to :ocv:func:`CvEM::train`) returns probabilites :math:`p_{i,k}` to belong to a mixture component :math:`k`. @@ -251,6 +261,8 @@ Returns logarithm of likelihood. .. ocv:function:: double CvEM::get_log_likelihood() const +.. ocv:pyfunction:: cv2.EM.getLikelihood() -> likelihood + CvEM::getLikelihoodDelta ------------------------ @@ -260,6 +272,7 @@ Returns difference between logarithm of likelihood on the last iteration and log .. ocv:function:: double CvEM::get_log_likelihood_delta() const +.. ocv:pyfunction:: cv2.EM.getLikelihoodDelta() -> likelihood delta CvEM::write_params ------------------ diff --git a/modules/ml/doc/gradient_boosted_trees.rst b/modules/ml/doc/gradient_boosted_trees.rst index 216b310c51..ee5460f3c1 100644 --- a/modules/ml/doc/gradient_boosted_trees.rst +++ b/modules/ml/doc/gradient_boosted_trees.rst @@ -161,6 +161,8 @@ Default and training constructors. .. ocv:cfunction:: CvGBTrees::CvGBTrees( const CvMat* trainData, int tflag, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, const CvMat* varType=0, const CvMat* missingDataMask=0, CvGBTreesParams params=CvGBTreesParams() ) +.. ocv:pyfunction:: cv2.GBTrees([trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params]]]]]]) -> + The constructors follow conventions of :ocv:func:`CvStatModel::CvStatModel`. See :ocv:func:`CvStatModel::train` for parameters descriptions. CvGBTrees::train @@ -169,8 +171,8 @@ Trains a Gradient boosted tree model. .. ocv:function:: bool CvGBTrees::train(const Mat& trainData, int tflag, const Mat& responses, const Mat& varIdx=Mat(), const Mat& sampleIdx=Mat(), const Mat& varType=Mat(), const Mat& missingDataMask=Mat(), CvGBTreesParams params=CvGBTreesParams(), bool update=false) -.. ocv:pyfunction:: cv2.CvGBTrees.train(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params[, update]]]]]]) -> retval - +.. ocv:pyfunction:: cv2.GBTrees.train(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params[, update]]]]]]) -> retval + .. ocv:cfunction:: bool CvGBTrees::train( const CvMat* trainData, int tflag, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, const CvMat* varType=0, const CvMat* missingDataMask=0, CvGBTreesParams params=CvGBTreesParams(), bool update=false ) .. ocv:cfunction:: bool CvGBTrees::train(CvMLData* data, CvGBTreesParams params=CvGBTreesParams(), bool update=false) @@ -196,8 +198,8 @@ Predicts a response for an input sample. .. ocv:function:: float CvGBTrees::predict(const Mat& sample, const Mat& missing=Mat(), const Range& slice = Range::all(), int k=-1) const -.. ocv:pyfunction:: cv2.CvGBTrees.predict(sample[, missing[, slice[, k]]]) -> retval - +.. ocv:pyfunction:: cv2.GBTrees.predict(sample[, missing[, slice[, k]]]) -> retval + .. ocv:cfunction:: float CvGBTrees::predict( const CvMat* sample, const CvMat* missing=0, CvMat* weakResponses=0, CvSlice slice = CV_WHOLE_SEQ, int k=-1 ) const :param sample: Input feature vector that has the same format as every training set @@ -239,8 +241,8 @@ Clears the model. .. ocv:function:: void CvGBTrees::clear() -.. ocv:pyfunction:: cv2.CvGBTrees.clear() -> None - +.. ocv:pyfunction:: cv2.GBTrees.clear() -> None + The function deletes the data set information and all the weak models and sets all internal variables to the initial state. The function is called in :ocv:func:`CvGBTrees::train` and in the destructor. diff --git a/modules/ml/doc/k_nearest_neighbors.rst b/modules/ml/doc/k_nearest_neighbors.rst index 053092ff35..00a250d924 100644 --- a/modules/ml/doc/k_nearest_neighbors.rst +++ b/modules/ml/doc/k_nearest_neighbors.rst @@ -29,7 +29,7 @@ Trains the model. .. ocv:function:: bool CvKNearest::train( const Mat& trainData, const Mat& responses, const Mat& sampleIdx=Mat(), bool isRegression=false, int maxK=32, bool updateBase=false ) -.. ocv:pyfunction:: cv2.CvKNearest.train(trainData, responses[, sampleIdx[, isRegression[, maxK[, updateBase]]]]) -> retval +.. ocv:pyfunction:: cv2.KNearest.train(trainData, responses[, sampleIdx[, isRegression[, maxK[, updateBase]]]]) -> retval .. ocv:cfunction:: bool CvKNearest::train( const CvMat* trainData, const CvMat* responses, const CvMat* sampleIdx=0, bool is_regression=false, int maxK=32, bool updateBase=false ) @@ -54,7 +54,7 @@ Finds the neighbors and predicts responses for input vectors. .. ocv:function:: float CvKNearest::find_nearest( const Mat& samples, int k, Mat& results, Mat& neighborResponses, Mat& dists) const -.. ocv:pyfunction:: cv2.CvKNearest.find_nearest(samples, k[, results[, neighborResponses[, dists]]]) -> retval, results, neighborResponses, dists +.. ocv:pyfunction:: cv2.KNearest.find_nearest(samples, k[, results[, neighborResponses[, dists]]]) -> retval, results, neighborResponses, dists .. ocv:cfunction:: float CvKNearest::find_nearest( const CvMat* samples, int k, CvMat* results=0, const float** neighbors=0, CvMat* neighborResponses=0, CvMat* dist=0 ) const diff --git a/modules/ml/doc/neural_networks.rst b/modules/ml/doc/neural_networks.rst index 069ffe42dc..327cacb216 100644 --- a/modules/ml/doc/neural_networks.rst +++ b/modules/ml/doc/neural_networks.rst @@ -88,20 +88,12 @@ ML implements two algorithms for training MLP's. The first algorithm is a classi random sequential back-propagation algorithm. The second (default) one is a batch RPROP algorithm. -References: +.. [BackPropWikipedia] http://en.wikipedia.org/wiki/Backpropagation. Wikipedia article about the back-propagation algorithm. -* - http://en.wikipedia.org/wiki/Backpropagation - . Wikipedia article about the back-propagation algorithm. - -* - Y. LeCun, L. Bottou, G.B. Orr and K.-R. Muller, *Efficient backprop*, in Neural Networks---Tricks of the Trade, Springer Lecture Notes in Computer Sciences 1524, pp.5-50, 1998. - -.. _RPROP93: - -* - [RPROP93] M. Riedmiller and H. Braun, *A Direct Adaptive Method for Faster Backpropagation Learning: The RPROP Algorithm*, Proc. ICNN, San Francisco (1993). +.. [LeCun98] Y. LeCun, L. Bottou, G.B. Orr and K.-R. Muller, *Efficient backprop*, in Neural Networks---Tricks of the Trade, Springer Lecture Notes in Computer Sciences 1524, pp.5-50, 1998. +.. [RPROP93] M. Riedmiller and H. Braun, *A Direct Adaptive Method for Faster Backpropagation Learning: The RPROP Algorithm*, Proc. ICNN, San Francisco (1993). + CvANN_MLP_TrainParams --------------------- @@ -119,7 +111,7 @@ The back-propagation algorithm parameters: Strength of the momentum term (the difference between weights on the 2 previous iterations). This parameter provides some inertia to smooth the random fluctuations of the weights. It can vary from 0 (the feature is disabled) to 1 and beyond. The value 0.1 or so is good enough -The RPROP algorithm parameters (see :ref:`[RPROP93] ` for details): +The RPROP algorithm parameters (see [RPROP93]_ for details): .. ocv:member:: double rp_dw0 @@ -192,6 +184,8 @@ The constructors. .. ocv:cfunction:: CvANN_MLP::CvANN_MLP( const CvMat* layerSizes, int activateFunc=CvANN_MLP::SIGMOID_SYM, double fparam1=0, double fparam2=0 ) +.. ocv:pyfunction:: cv2.ANN_MLP(layerSizes[, activateFunc[, fparam1[, fparam2]]]) -> + The advanced constructor allows to create MLP with the specified topology. See :ocv:func:`CvANN_MLP::create` for details. CvANN_MLP::create @@ -202,6 +196,8 @@ Constructs MLP with the specified topology. .. ocv:cfunction:: void CvANN_MLP::create( const CvMat* layerSizes, int activateFunc=CvANN_MLP::SIGMOID_SYM, double fparam1=0, double fparam2=0 ) +.. ocv:pyfunction:: cv2.ANN_MLP.create(layerSizes[, activateFunc[, fparam1[, fparam2]]]) -> None + :param layerSizes: Integer vector specifying the number of neurons in each layer including the input and output layers. :param activateFunc: Parameter specifying the activation function for each neuron: one of ``CvANN_MLP::IDENTITY``, ``CvANN_MLP::SIGMOID_SYM``, and ``CvANN_MLP::GAUSSIAN``. @@ -218,6 +214,8 @@ Trains/updates MLP. .. ocv:cfunction:: int CvANN_MLP::train( const CvMat* inputs, const CvMat* outputs, const CvMat* sampleWeights, const CvMat* sampleIdx=0, CvANN_MLP_TrainParams params = CvANN_MLP_TrainParams(), int flags=0 ) +.. ocv:pyfunction:: cv2.ANN_MLP.train(inputs, outputs, sampleWeights[, sampleIdx[, params[, flags]]]) -> niterations + :param inputs: Floating-point matrix of input vectors, one vector per row. :param outputs: Floating-point matrix of the corresponding output vectors, one vector per row. @@ -246,6 +244,8 @@ Predicts responses for input samples. .. ocv:cfunction:: float CvANN_MLP::predict( const CvMat* inputs, CvMat* outputs ) const +.. ocv:pyfunction:: cv2.ANN_MLP.predict(inputs, outputs) -> retval + :param inputs: Input samples. :param outputs: Predicted responses for corresponding samples. @@ -273,3 +273,4 @@ Returns neurons weights of the particular layer. .. ocv:function:: double* CvANN_MLP::get_weights(int layer) :param layer: Index of the particular layer. + \ No newline at end of file diff --git a/modules/ml/doc/normal_bayes_classifier.rst b/modules/ml/doc/normal_bayes_classifier.rst index 28f4937372..3f345680d1 100644 --- a/modules/ml/doc/normal_bayes_classifier.rst +++ b/modules/ml/doc/normal_bayes_classifier.rst @@ -7,7 +7,7 @@ Normal Bayes Classifier This simple classification model assumes that feature vectors from each class are normally distributed (though, not necessarily independently distributed). So, the whole data distribution function is assumed to be a Gaussian mixture, one component per class. Using the training data the algorithm estimates mean vectors and covariance matrices for every class, and then it uses them for prediction. -[Fukunaga90] K. Fukunaga. *Introduction to Statistical Pattern Recognition*. second ed., New York: Academic Press, 1990. +.. [Fukunaga90] K. Fukunaga. *Introduction to Statistical Pattern Recognition*. second ed., New York: Academic Press, 1990. CvNormalBayesClassifier ----------------------- @@ -25,6 +25,8 @@ Default and training constructors. .. ocv:cfunction:: CvNormalBayesClassifier::CvNormalBayesClassifier( const CvMat* trainData, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0 ) +.. ocv:pyfunction:: cv2.NormalBayesClassifier(trainData, responses[, varIdx[, sampleIdx]]) -> + The constructors follow conventions of :ocv:func:`CvStatModel::CvStatModel`. See :ocv:func:`CvStatModel::train` for parameters descriptions. CvNormalBayesClassifier::train @@ -33,7 +35,7 @@ Trains the model. .. ocv:function:: bool CvNormalBayesClassifier::train( const Mat& trainData, const Mat& responses, const Mat& varIdx = Mat(), const Mat& sampleIdx=Mat(), bool update=false ) -.. ocv:pyfunction:: cv2.CvNormalBayesClassifier.train(trainData, responses[, varIdx[, sampleIdx[, update]]]) -> retval +.. ocv:pyfunction:: cv2.NormalBayesClassifier.train(trainData, responses[, varIdx[, sampleIdx[, update]]]) -> retval .. ocv:cfunction:: bool CvNormalBayesClassifier::train( const CvMat* trainData, const CvMat* responses, const CvMat* varIdx = 0, const CvMat* sampleIdx=0, bool update=false ) @@ -52,7 +54,7 @@ Predicts the response for sample(s). .. ocv:function:: float CvNormalBayesClassifier::predict( const Mat& samples, Mat* results=0 ) const -.. ocv:pyfunction:: cv2.CvNormalBayesClassifier.predict(samples) -> retval, results +.. ocv:pyfunction:: cv2.NormalBayesClassifier.predict(samples) -> retval, results .. ocv:cfunction:: float CvNormalBayesClassifier::predict( const CvMat* samples, CvMat* results=0 ) const diff --git a/modules/ml/doc/random_trees.rst b/modules/ml/doc/random_trees.rst index 53035322fd..e4f46031d9 100644 --- a/modules/ml/doc/random_trees.rst +++ b/modules/ml/doc/random_trees.rst @@ -114,7 +114,7 @@ Trains the Random Trees model. .. ocv:cfunction:: bool CvRTrees::train( CvMLData* data, CvRTParams params=CvRTParams() ) -.. ocv:pyfunction:: cv2.CvRTrees.train(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params]]]]]) -> retval +.. ocv:pyfunction:: cv2.RTrees.train(trainData, tflag, responses[, varIdx[, sampleIdx[, varType[, missingDataMask[, params]]]]]) -> retval The method :ocv:func:`CvRTrees::train` is very similar to the method :ocv:func:`CvDTree::train` and follows the generic method :ocv:func:`CvStatModel::train` conventions. All the parameters specific to the algorithm training are passed as a :ocv:class:`CvRTParams` instance. The estimate of the training error (``oob-error``) is stored in the protected class member ``oob_error``. @@ -126,7 +126,7 @@ Predicts the output for an input sample. .. ocv:cfunction:: float CvRTrees::predict( const CvMat* sample, const CvMat* missing = 0 ) const -.. ocv:pyfunction:: cv2.CvRTrees.predict(sample[, missing]) -> retval +.. ocv:pyfunction:: cv2.RTrees.predict(sample[, missing]) -> retval :param sample: Sample for classification. @@ -143,7 +143,7 @@ Returns a fuzzy-predicted class label. .. ocv:cfunction:: float CvRTrees::predict_prob( const CvMat* sample, const CvMat* missing = 0 ) const -.. ocv:pyfunction:: cv2.CvRTrees.predict_prob(sample[, missing]) -> retval +.. ocv:pyfunction:: cv2.RTrees.predict_prob(sample[, missing]) -> retval :param sample: Sample for classification. @@ -158,6 +158,8 @@ Returns the variable importance array. .. ocv:function:: Mat CvRTrees::getVarImportance() +.. ocv:pyfunction:: cv2.RTrees.getVarImportance() -> importanceVector + .. ocv:cfunction:: const CvMat* CvRTrees::get_var_importance() The method returns the variable importance vector, computed at the training stage when ``CvRTParams::calc_var_importance`` is set to true. If this flag was set to false, the ``NULL`` pointer is returned. This differs from the decision trees where variable importance can be computed anytime after the training. diff --git a/modules/ml/doc/statistical_models.rst b/modules/ml/doc/statistical_models.rst index 571fd4cf64..8e2bb014dd 100644 --- a/modules/ml/doc/statistical_models.rst +++ b/modules/ml/doc/statistical_models.rst @@ -89,7 +89,7 @@ Saves the model to a file. .. ocv:function:: void CvStatModel::save( const char* filename, const char* name=0 ) -.. ocv:pyfunction:: cv2.CvStatModel.save(filename[, name]) -> None +.. ocv:pyfunction:: cv2.StatModel.save(filename[, name]) -> None The method ``save`` saves the complete model state to the specified XML or YAML file with the specified name or default name (which depends on a particular class). *Data persistence* functionality from ``CxCore`` is used. @@ -99,7 +99,7 @@ Loads the model from a file. .. ocv:function:: void CvStatModel::load( const char* filename, const char* name=0 ) -.. ocv:pyfunction:: cv2.CvStatModel.load(filename[, name]) -> None +.. ocv:pyfunction:: cv2.StatModel.load(filename[, name]) -> None The method ``load`` loads the complete model state with the specified name (or default model-dependent name) from the specified XML or YAML file. The previous model state is cleared by :ocv:func:`CvStatModel::clear`. diff --git a/modules/ml/doc/support_vector_machines.rst b/modules/ml/doc/support_vector_machines.rst index c0deaec43d..bad2d53eca 100644 --- a/modules/ml/doc/support_vector_machines.rst +++ b/modules/ml/doc/support_vector_machines.rst @@ -7,29 +7,11 @@ Originally, support vector machines (SVM) was a technique for building an optima The solution is optimal, which means that the margin between the separating hyper-plane and the nearest feature vectors from both classes (in case of 2-class classifier) is maximal. The feature vectors that are the closest to the hyper-plane are called *support vectors*, which means that the position of other vectors does not affect the hyper-plane (the decision function). -There are a lot of good references on SVM. You may consider starting with the following: +SVM implementation in OpenCV is based on [LibSVM]_. -* - [Burges98] C. Burges. *A tutorial on support vector machines for pattern recognition*, Knowledge Discovery and Data Mining 2(2), 1998. - (available online at - http://citeseer.ist.psu.edu/burges98tutorial.html - ). +.. [Burges98] C. Burges. *A tutorial on support vector machines for pattern recognition*, Knowledge Discovery and Data Mining 2(2), 1998 (available online at http://citeseer.ist.psu.edu/burges98tutorial.html) -* - Chih-Chung Chang and Chih-Jen Lin. *LIBSVM - A Library for Support Vector Machines* - ( - http://www.csie.ntu.edu.tw/~cjlin/libsvm/ - ) - -For details of implementation and various SVM formulations see: - -.. _LIBSVM: - -* - [LibSVM] C.-C. Chang and C.-J. Lin. *LIBSVM: a library for support vector machines*, ACM Transactions on Intelligent Systems and Technology, 2:27:1--27:27, 2011. - ( - http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.pdf - ) +.. [LibSVM] C.-C. Chang and C.-J. Lin. *LIBSVM: a library for support vector machines*, ACM Transactions on Intelligent Systems and Technology, 2:27:1--27:27, 2011. (http://www.csie.ntu.edu.tw/~cjlin/papers/libsvm.pdf) CvParamGrid @@ -121,7 +103,7 @@ The constructors. * **CvSVM::NU_SVR** :math:`\nu`-Support Vector Regression. :math:`\nu` is used instead of ``p``. - See :ref:`[LibSVM] ` for details. + See [LibSVM]_ for details. :param kernel_type: Type of a SVM kernel. Possible values are: @@ -178,6 +160,8 @@ Default and training constructors. .. ocv:cfunction:: CvSVM::CvSVM( const CvMat* trainData, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, CvSVMParams params=CvSVMParams() ) +.. ocv:pyfunction:: cv2.SVM(trainData, responses[, varIdx[, sampleIdx[, params]]]) -> + The constructors follow conventions of :ocv:func:`CvStatModel::CvStatModel`. See :ocv:func:`CvStatModel::train` for parameters descriptions. CvSVM::train @@ -188,7 +172,7 @@ Trains an SVM. .. ocv:cfunction:: bool CvSVM::train( const CvMat* trainData, const CvMat* responses, const CvMat* varIdx=0, const CvMat* sampleIdx=0, CvSVMParams params=CvSVMParams() ) -.. ocv:pyfunction:: cv2.CvSVM.train(trainData, responses[, varIdx[, sampleIdx[, params]]]) -> retval +.. ocv:pyfunction:: cv2.SVM.train(trainData, responses[, varIdx[, sampleIdx[, params]]]) -> retval The method trains the SVM model. It follows the conventions of the generic :ocv:func:`CvStatModel::train` approach with the following limitations: @@ -212,6 +196,8 @@ Trains an SVM with optimal parameters. .. ocv:cfunction:: bool CvSVM::train_auto( const CvMat* trainData, const CvMat* responses, const CvMat* varIdx, const CvMat* sampleIdx, CvSVMParams params, int kfold = 10, CvParamGrid Cgrid = get_default_grid(CvSVM::C), CvParamGrid gammaGrid = get_default_grid(CvSVM::GAMMA), CvParamGrid pGrid = get_default_grid(CvSVM::P), CvParamGrid nuGrid = get_default_grid(CvSVM::NU), CvParamGrid coeffGrid = get_default_grid(CvSVM::COEF), CvParamGrid degreeGrid = get_default_grid(CvSVM::DEGREE), bool balanced=false ) +.. ocv:pyfunction:: cv2.SVM.train_auto(trainData, responses, varIdx, sampleIdx, params[, k_fold[, Cgrid[, gammaGrid[, pGrid[, nuGrid[, coeffGrid[, degreeGrid[, balanced]]]]]]]]) -> retval + :param k_fold: Cross-validation parameter. The training set is divided into ``k_fold`` subsets. One subset is used to train the model, the others form the test set. So, the SVM algorithm is executed ``k_fold`` times. :param \*Grid: Iteration grid for the corresponding SVM parameter. @@ -244,6 +230,8 @@ Predicts the response for input sample(s). .. ocv:cfunction:: float CvSVM::predict( const CvMat* samples, CvMat* results ) const +.. ocv:pyfunction:: cv2.SVM.predict(sample[, returnDFVal]) -> retval + :param sample(s): Input sample(s) for prediction. :param returnDFVal: Specifies a type of the return value. If ``true`` and the problem is 2-class classification then the method returns the decision function value that is signed distance to the margin, else the function returns a class label (classification) or estimated function value (regression). @@ -292,6 +280,8 @@ Retrieves a number of support vectors and the particular vector. .. ocv:function:: const float* CvSVM::get_support_vector(int i) const +.. ocv:pyfunction:: cv2.SVM.get_support_vector_count() -> nsupportVectors + :param i: Index of the particular support vector. The methods can be used to retrieve a set of support vectors. @@ -301,3 +291,5 @@ CvSVM::get_var_count Returns the number of used features (variables count). .. ocv:function:: int CvSVM::get_var_count() const + +.. ocv:pyfunction:: cv2.SVM.get_var_count() -> nvars diff --git a/modules/objdetect/doc/cascade_classification.rst b/modules/objdetect/doc/cascade_classification.rst index 246770a54e..9db8e89156 100644 --- a/modules/objdetect/doc/cascade_classification.rst +++ b/modules/objdetect/doc/cascade_classification.rst @@ -3,6 +3,35 @@ Cascade Classification .. highlight:: cpp +Haar Feature-based Cascade Classifier for Object Detection +---------------------------------------------------------- + +The object detector described below has been initially proposed by Paul Viola [Viola01]_ and improved by Rainer Lienhart [Lienhart02]_. + +First, a classifier (namely a *cascade of boosted classifiers working with haar-like features*) is trained with a few hundred sample views of a particular object (i.e., a face or a car), called positive examples, that are scaled to the same size (say, 20x20), and negative examples - arbitrary images of the same size. + +After a classifier is trained, it can be applied to a region of interest (of the same size as used during the training) in an input image. The classifier outputs a "1" if the region is likely to show the object (i.e., face/car), and "0" otherwise. To search for the object in the whole image one can move the search window across the image and check every location using the classifier. The classifier is designed so that it can be easily "resized" in order to be able to find the objects of interest at different sizes, which is more efficient than resizing the image itself. So, to find an object of an unknown size in the image the scan procedure should be done several times at different scales. + +The word "cascade" in the classifier name means that the resultant classifier consists of several simpler classifiers (*stages*) that are applied subsequently to a region of interest until at some stage the candidate is rejected or all the stages are passed. The word "boosted" means that the classifiers at every stage of the cascade are complex themselves and they are built out of basic classifiers using one of four different ``boosting`` techniques (weighted voting). Currently Discrete Adaboost, Real Adaboost, Gentle Adaboost and Logitboost are supported. The basic classifiers are decision-tree classifiers with at least 2 leaves. Haar-like features are the input to the basic classifers, and are calculated as described below. The current algorithm uses the following Haar-like features: + + +.. image:: pics/haarfeatures.png + + +The feature used in a particular classifier is specified by its shape (1a, 2b etc.), position within the region of interest and the scale (this scale is not the same as the scale used at the detection stage, though these two scales are multiplied). For example, in the case of the third line feature (2c) the response is calculated as the difference between the sum of image pixels under the rectangle covering the whole feature (including the two white stripes and the black stripe in the middle) and the sum of the image pixels under the black stripe multiplied by 3 in order to compensate for the differences in the size of areas. The sums of pixel values over a rectangular regions are calculated rapidly using integral images (see below and the :ocv:func:`integral` description). + +To see the object detector at work, have a look at the facedetect demo: +https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/facedetect.cpp + +The following reference is for the detection part only. There is a separate application called ``opencv_traincascade`` that can train a cascade of boosted classifiers from a set of samples. + +.. note:: In the new C++ interface it is also possible to use LBP (local binary pattern) features in addition to Haar-like features. + +.. [Viola01] Paul Viola and Michael J. Jones. Rapid Object Detection using a Boosted Cascade of Simple Features. IEEE CVPR, 2001. The paper is available online at http://www.ai.mit.edu/people/viola/ + +.. [Lienhart02] Rainer Lienhart and Jochen Maydt. An Extended Set of Haar-like Features for Rapid Object Detection. IEEE ICIP 2002, Vol. 1, pp. 900-903, Sep. 2002. This paper, as well as the extended technical report, can be retrieved at http://www.lienhart.de/Publications/publications.html + + FeatureEvaluator ---------------- .. ocv:class:: FeatureEvaluator @@ -111,76 +140,7 @@ CascadeClassifier ----------------- .. ocv:class:: CascadeClassifier -Cascade classifier class for object detection. :: - - class CascadeClassifier - { - public: - // structure for storing a tree node - struct CV_EXPORTS DTreeNode - { - int featureIdx; // index of the feature on which we perform the split - float threshold; // split threshold of ordered features only - int left; // left child index in the tree nodes array - int right; // right child index in the tree nodes array - }; - - // structure for storing a decision tree - struct CV_EXPORTS DTree - { - int nodeCount; // nodes count - }; - - // structure for storing a cascade stage (BOOST only for now) - struct CV_EXPORTS Stage - { - int first; // first tree index in tree array - int ntrees; // number of trees - float threshold; // threshold of stage sum - }; - - enum { BOOST = 0 }; // supported stage types - - // mode of detection (see parameter flags in function HaarDetectObjects) - enum { DO_CANNY_PRUNING = CV_HAAR_DO_CANNY_PRUNING, - SCALE_IMAGE = CV_HAAR_SCALE_IMAGE, - FIND_BIGGEST_OBJECT = CV_HAAR_FIND_BIGGEST_OBJECT, - DO_ROUGH_SEARCH = CV_HAAR_DO_ROUGH_SEARCH }; - - CascadeClassifier(); // default constructor - CascadeClassifier(const string& filename); - ~CascadeClassifier(); // destructor - - bool empty() const; - bool load(const string& filename); - bool read(const FileNode& node); - - void detectMultiScale( const Mat& image, vector& objects, - double scaleFactor=1.1, int minNeighbors=3, - int flags=0, Size minSize=Size()); - - bool setImage( Ptr&, const Mat& ); - int runAt( Ptr&, Point ); - - bool is_stump_based; // true, if the trees are stumps - - int stageType; // stage type (BOOST only for now) - int featureType; // feature type (HAAR or LBP for now) - int ncategories; // number of categories (for categorical features only) - Size origWinSize; // size of training images - - vector stages; // vector of stages (BOOST for now) - vector classifiers; // vector of decision trees - vector nodes; // vector of tree nodes - vector leaves; // vector of leaf values - vector subsets; // subsets of split by categorical feature - - Ptr feval; // pointer to feature evaluator - Ptr oldCascade; // pointer to old cascade - }; - - - +Cascade classifier class for object detection. CascadeClassifier::CascadeClassifier ---------------------------------------- @@ -188,6 +148,8 @@ Loads a classifier from a file. .. ocv:function:: CascadeClassifier::CascadeClassifier(const string& filename) +.. ocv:pyfunction:: cv2.CascadeClassifier(filename) -> + :param filename: Name of the file from which the classifier is loaded. @@ -231,6 +193,12 @@ Detects objects of different sizes in the input image. The detected objects are .. ocv:pyfunction:: cv2.CascadeClassifier.detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]) -> objects .. ocv:pyfunction:: cv2.CascadeClassifier.detectMultiScale(image, rejectLevels, levelWeights[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize[, outputRejectLevels]]]]]]) -> objects +.. ocv:cfunction:: CvSeq* cvHaarDetectObjects( const CvArr* image, CvHaarClassifierCascade* cascade, CvMemStorage* storage, double scaleFactor=1.1, int minNeighbors=3, int flags=0, CvSize minSize=cvSize(0, 0), CvSize maxSize=cvSize(0, 0) ) + +.. ocv:pyoldfunction:: cv.HaarDetectObjects(image, cascade, storage, scaleFactor=1.1, minNeighbors=3, flags=0, minSize=(0, 0))-> detectedObjects + + :param cascade: Haar classifier cascade (OpenCV 1.x API only). It can be loaded from XML or YAML file using :ocv:cfunc:`Load`. When the cascade is not needed anymore, release it using ``cvReleaseHaarClassifierCascade(&cascade)``. + :param image: Matrix of the type ``CV_8U`` containing an image where objects are detected. :param objects: Vector of rectangles where each rectangle contains the detected object. @@ -247,22 +215,33 @@ Detects objects of different sizes in the input image. The detected objects are CascadeClassifier::setImage ------------------------------- -Sets an image for detection that is called by ``detectMultiScale`` at each image level. +Sets an image for detection. .. ocv:function:: bool CascadeClassifier::setImage( Ptr& feval, const Mat& image ) +.. ocv:cfunction:: void cvSetImagesForHaarClassifierCascade( CvHaarClassifierCascade* cascade, const CvArr* sum, const CvArr* sqsum, const CvArr* tiltedSum, double scale ) + + :param cascade: Haar classifier cascade (OpenCV 1.x API only). See :ocv:func:`CascadeClassifier::detectMultiScale` for more information. + :param feval: Pointer to the feature evaluator used for computing features. :param image: Matrix of the type ``CV_8UC1`` containing an image where the features are computed. +The function is automatically called by :ocv:func:`CascadeClassifier::detectMultiScale` at every image scale. But if you want to test various locations manually using :ocv:func:`CascadeClassifier::runAt`, you need to call the function before, so that the integral images are computed. + +.. note:: in the old API you need to supply integral images (that can be obtained using :ocv:cfunc:`Integral`) instead of the original image. CascadeClassifier::runAt ---------------------------- -Runs the detector at the specified point. Use ``setImage`` to set the image for the detector to work with. +Runs the detector at the specified point. .. ocv:function:: int CascadeClassifier::runAt( Ptr& feval, Point pt ) +.. ocv:cfunction:: int cvRunHaarClassifierCascade( CvHaarClassifierCascade* cascade, CvPoint pt, int startStage=0 ) + + :param cascade: Haar classifier cascade (OpenCV 1.x API only). See :ocv:func:`CascadeClassifier::detectMultiScale` for more information. + :param feval: Feature evaluator used for computing features. :param pt: Upper left point of the window where the features are computed. Size of the window is equal to the size of training images. @@ -270,13 +249,13 @@ Runs the detector at the specified point. Use ``setImage`` to set the image for The function returns 1 if the cascade classifier detects an object in the given location. Otherwise, it returns negated index of the stage at which the candidate has been rejected. - +Use :ocv:func:`CascadeClassifier::setImage` to set the image for the detector to work with. groupRectangles ------------------- Groups the object candidate rectangles. -.. ocv:function:: void groupRectangles(vector& rectList, int groupThreshold, double eps=0.2) +.. ocv:function:: void groupRectangles(vector& rectList, int groupThreshold, double eps=0.2) .. ocv:pyfunction:: cv2.groupRectangles(rectList, groupThreshold[, eps]) -> None .. ocv:pyfunction:: cv2.groupRectangles(rectList, groupThreshold[, eps]) -> weights diff --git a/doc/pics/haarfeatures.png b/modules/objdetect/doc/pics/haarfeatures.png similarity index 100% rename from doc/pics/haarfeatures.png rename to modules/objdetect/doc/pics/haarfeatures.png diff --git a/modules/python/src2/gen2.py b/modules/python/src2/gen2.py index dde0ee50ef..65be794212 100644 --- a/modules/python/src2/gen2.py +++ b/modules/python/src2/gen2.py @@ -443,7 +443,10 @@ class FuncInfo(object): # we write ClassName([args ...]) -> object if have_empty_constructor and len(self.variants) == 2: idx = self.variants[1].py_arglist != [] - docstring_list = ["[" + self.variants[idx].py_docstring + "]"] + s = self.variants[idx].py_docstring + p1 = s.find("(") + p2 = s.rfind(")") + docstring_list = [s[:p1+1] + "[" + s[p1+2:p2] + "]" + s[p2:]] return Template(' {"$py_funcname", (PyCFunction)$wrap_funcname, METH_KEYWORDS, "$py_docstring"},\n' ).substitute(py_funcname = self.variants[0].wname, wrap_funcname=self.get_wrapper_name(), diff --git a/modules/refman.rst b/modules/refman.rst index d25d3c1d25..6ed01a4cd2 100644 --- a/modules/refman.rst +++ b/modules/refman.rst @@ -1,5 +1,5 @@ ############################ -OpenCV 2.x C++ API Reference +OpenCV API Reference ############################ .. toctree:: diff --git a/modules/video/doc/motion_analysis_and_object_tracking.rst b/modules/video/doc/motion_analysis_and_object_tracking.rst index cd1f39e252..ff97776817 100644 --- a/modules/video/doc/motion_analysis_and_object_tracking.rst +++ b/modules/video/doc/motion_analysis_and_object_tracking.rst @@ -41,8 +41,7 @@ Calculates an optical flow for a sparse feature set using the iterative Lucas-Ka * **OPTFLOW_USE_INITIAL_FLOW** Use initial estimations stored in ``nextPts`` . If the flag is not set, then ``prevPts`` is copied to ``nextPts`` and is considered as the initial estimate. The function implements a sparse iterative version of the Lucas-Kanade optical flow in pyramids. See -Bouguet00 -. +[Bouguet00]_. @@ -78,7 +77,7 @@ Computes a dense optical flow using the Gunnar Farneback's algorithm. * **OPTFLOW_FARNEBACK_GAUSSIAN** Use the Gaussian :math:`\texttt{winsize}\times\texttt{winsize}` filter instead of a box filter of the same size for optical flow estimation. Usually, this option gives z more accurate flow than with a box filter, at the cost of lower speed. Normally, ``winsize`` for a Gaussian window should be set to a larger value to achieve the same level of robustness. -The function finds an optical flow for each ``prevImg`` pixel using the alorithm so that +The function finds an optical flow for each ``prevImg`` pixel using the [Farneback2003]_ alorithm so that .. math:: @@ -143,7 +142,7 @@ Calculates the optical flow for two images using Horn-Schunck algorithm. :param criteria: Criteria of termination of velocity computing -The function computes the flow for every pixel of the first input image using the Horn and Schunck algorithm Horn81. The function is obsolete. To track sparse features, use :ocv:func:`calcOpticalFlowPyrLK`. To track all the pixels, use :ocv:func:`calcOpticalFlowFarneback`. +The function computes the flow for every pixel of the first input image using the Horn and Schunck algorithm [Horn81]_. The function is obsolete. To track sparse features, use :ocv:func:`calcOpticalFlowPyrLK`. To track all the pixels, use :ocv:func:`calcOpticalFlowFarneback`. CalcOpticalFlowLK @@ -165,7 +164,7 @@ Calculates the optical flow for two images using Lucas-Kanade algorithm. :param vely: Vertical component of the optical flow of the same size as input images, 32-bit floating-point, single-channel -The function computes the flow for every pixel of the first input image using the Lucas and Kanade algorithm Lucas81. The function is obsolete. To track sparse features, use :ocv:func:`calcOpticalFlowPyrLK`. To track all the pixels, use :ocv:func:`calcOpticalFlowFarneback`. +The function computes the flow for every pixel of the first input image using the Lucas and Kanade algorithm [Lucas81]_. The function is obsolete. To track sparse features, use :ocv:func:`calcOpticalFlowPyrLK`. To track all the pixels, use :ocv:func:`calcOpticalFlowFarneback`. estimateRigidTransform @@ -243,9 +242,9 @@ That is, MHI pixels where the motion occurs are set to the current ``timestamp`` The function, together with :ocv:func:`calcMotionGradient` and :ocv:func:`calcGlobalOrientation` , implements a motion templates technique described in -Davis97 +[Davis97]_ and -Bradski00 +[Bradski00]_ . See also the OpenCV sample ``motempl.c`` that demonstrates the use of all the motion template functions. @@ -364,8 +363,7 @@ Finds an object center, size, and orientation. :param criteria: Stop criteria for the underlying :ocv:func:`meanShift` . The function implements the CAMSHIFT object tracking algrorithm -Bradski98 -. +[Bradski98]_. First, it finds an object center using :ocv:func:`meanShift` and then adjusts the window size and finds the optimal rotation. The function returns the rotated rectangle structure that includes the object position, size, and orientation. The next position of the search window can be obtained with ``RotatedRect::boundingRect()`` . @@ -407,8 +405,7 @@ KalmanFilter Kalman filter class. The class implements a standard Kalman filter -http://en.wikipedia.org/wiki/Kalman_filter -. However, you can modify ``transitionMatrix``, ``controlMatrix``, and ``measurementMatrix`` to get an extended Kalman filter functionality. See the OpenCV sample ``kalman.cpp`` . +http://en.wikipedia.org/wiki/Kalman_filter, [Welch95]_. However, you can modify ``transitionMatrix``, ``controlMatrix``, and ``measurementMatrix`` to get an extended Kalman filter functionality. See the OpenCV sample ``kalman.cpp`` . @@ -421,6 +418,11 @@ The constructors. .. ocv:function:: KalmanFilter::KalmanFilter(int dynamParams, int measureParams, int controlParams=0, int type=CV_32F) +.. ocv:pyfunction:: cv2.KalmanFilter(dynamParams, measureParams[, controlParams[, type]]) -> + +.. ocv:cfunction:: CvKalman* cvCreateKalman( int dynamParams, int measureParams, int controlParams=0 ) +.. ocv:pyoldfunction:: cv.CreateKalman(dynamParams, measureParams, controlParams=0) -> CvKalman + The full constructor. :param dynamParams: Dimensionality of the state. @@ -431,6 +433,7 @@ The constructors. :param type: Type of the created matrices that should be ``CV_32F`` or ``CV_64F``. +.. note:: In C API when ``CvKalman* kalmanFilter`` structure is not needed anymore, it should be released with ``cvReleaseKalman(&kalmanFilter)`` KalmanFilter::init ------------------ @@ -447,7 +450,6 @@ Re-initializes Kalman filter. The previous content is destroyed. :param type: Type of the created matrices that should be ``CV_32F`` or ``CV_64F``. - KalmanFilter::predict --------------------- Computes a predicted state. @@ -456,6 +458,9 @@ Computes a predicted state. .. ocv:pyfunction:: cv2.KalmanFilter.predict([, control]) -> retval +.. ocv:cfunction:: const CvMat* cvKalmanPredict( CvKalman* kalman, const CvMat* control=NULL) +.. ocv:pyoldfunction:: cv.KalmanPredict(kalman, control=None) -> cvmat + :param control: The optional input control @@ -467,6 +472,9 @@ Updates the predicted state from the measurement. .. ocv:pyfunction:: cv2.KalmanFilter.correct(measurement) -> retval +.. ocv:cfunction:: const CvMat* cvKalmanCorrect( CvKalman* kalman, const CvMat* measurement ) +.. ocv:pyoldfunction:: cv.KalmanCorrect(kalman, measurement) -> cvmat + :param control: The measured system parameters @@ -489,19 +497,17 @@ Base class for background/foreground segmentation. :: The class is only used to define the common interface for the whole family of background/foreground segmentation algorithms. - - BackgroundSubtractor::operator() ------------------------------- Computes a foreground mask. .. ocv:function:: virtual void BackgroundSubtractor::operator()(InputArray image, OutputArray fgmask, double learningRate=0) +.. ocv:pyfunction:: cv2.BackgroundSubtractor.apply(image[, fgmask[, learningRate]]) -> fgmask + :param image: Next video frame. - :param fgmask: Foreground mask as an 8-bit binary image. - - + :param fgmask: The output foreground mask as an 8-bit binary image. BackgroundSubtractor::getBackgroundImage @@ -534,6 +540,8 @@ The contructors .. ocv:function:: BackgroundSubtractorMOG::BackgroundSubtractorMOG(int history, int nmixtures, double backgroundRatio, double noiseSigma=0) +.. ocv:pyfunction:: cv2.BackgroundSubtractorMOG(history, nmixtures, backgroundRatio[, noiseSigma]) -> + :param history: Length of the history. :param nmixtures: Number of Gaussian mixtures. @@ -638,6 +646,23 @@ BackgroundSubtractorMOG2::getBackgroundImage -------------------------------------------- Returns background image -.. ocv:function:: virtual void BackgroundSubtractorMOG2::getBackgroundImage(OutputArray backgroundImage) const +.. ocv:function:: virtual void BackgroundSubtractorMOG2::getBackgroundImage(OutputArray backgroundImage) - See :ocv:func:`BackgroundSubtractor::getBackgroundImage`. +See :ocv:func:`BackgroundSubtractor::getBackgroundImage`. + + +.. [Bouguet00] Jean-Yves Bouguet. Pyramidal Implementation of the Lucas Kanade Feature Tracker. + +.. [Bradski98] Bradski, G.R. "Computer Vision Face Tracking for Use in a Perceptual User Interface", Intel, 1998 + +.. [Bradski00] Davis, J.W. and Bradski, G.R. “Motion Segmentation and Pose Recognition with Motion History Gradients”, WACV00, 2000 + +.. [Davis97] Davis, J.W. and Bobick, A.F. “The Representation and Recognition of Action Using Temporal Templates”, CVPR97, 1997 + +.. [Farneback2003] Gunnar Farneback, Two-frame motion estimation based on polynomial expansion, Lecture Notes in Computer Science, 2003, (2749), , 363-370. + +.. [Horn81] Berthold K.P. Horn and Brian G. Schunck. Determining Optical Flow. Artificial Intelligence, 17, pp. 185-203, 1981. + +.. [Lucas81] Lucas, B., and Kanade, T. An Iterative Image Registration Technique with an Application to Stereo Vision, Proc. of 7th International Joint Conference on Artificial Intelligence (IJCAI), pp. 674-679. + +.. [Welch95] Greg Welch and Gary Bishop “An Introduction to the Kalman Filter”, 1995